Перейти к основному содержимому

Памятка: Почему такой формат практических работ

Важно

В большинстве задач этого курса вы НЕ найдёте готовых CREATE TABLE, INSERT и схем данных.

Это сделано специально и очень осознанно.

Почему так?

ПричинаЧто это даёт вам на практике
Вы учитесь проектировать схему с нуляРеальный разработчик почти никогда не получает готовую схему — он сам её придумывает
Развивается понимание связей и типов данныхВы сами решаете: SERIAL или UUID? NUMERIC или DOUBLE PRECISION? TEXT или VARCHAR(255)?
Тренируется работа с нормализацией / денормализациейПриходится думать: отдельная таблица или JSONB? 1NF–3NF или осознанная денормализация?
Вы учитесь писать миграцииCREATE TABLE, ALTER TABLE, ADD CONSTRAINT, CREATE INDEX — это ваш ежедневный хлеб
Развивается фантазия и предметная областьПридумываете сами поля: last_login, is_blocked, loyalty_points, delivery_address_json…
Ошибки становятся вашими лучшими учителямиЗабыли NOT NULL → потом сами же мучаетесь с NULL → больше никогда не забудете
Гораздо лучше запоминается синтаксисКогда сами пишете — он остаётся в голове надолго, а не пролетает мимо глаз
Подготовка к реальным собеседованиямНа 80% SQL-собеседований просят: «Нарисуй схему и напиши запросы для интернет-магазина/блога/CRM»

Что от вас ожидается в каждой практической работе

  1. Прочитайте условие внимательно
    Там обычно описана предметная область: интернет-магазин, блог, логи, сотрудники, финансы и т.д.

  2. Придумайте и создайте нужные таблицы

    • Первичные ключи
    • Внешние ключи
    • NOT NULL, CHECK, DEFAULT, UNIQUE где логично
    • Правильные типы данных (TIMESTAMPTZ, NUMERIC, JSONB и т.д.)
  3. Добавьте индексы

    • На часто фильтруемые поля
    • На внешние ключи
    • Составные индексы, где ожидается WHERE + ORDER BY
  4. Наполните тестовыми данными

    • 10–50 строк хватит для отладки
    • Можно использовать generate_series + random()
  5. Пишите решения

    • Используйте EXPLAIN ANALYZE, если задача на оптимизацию
    • Показывайте CREATE INDEX, если считаете нужным
  6. Думайте о краевых случаях

    • Что будет при NULL?
    • Что при отрицательном количестве?
    • Что при дубликате уникального поля?

Пример, как выглядит хорошее решение

-- 1. Проектируем схему
CREATE TABLE customers (
customer_id BIGSERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
full_name VARCHAR(100) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
is_active BOOLEAN NOT NULL DEFAULT true
);

CREATE TABLE orders (
order_id BIGSERIAL PRIMARY KEY,
customer_id BIGINT NOT NULL REFERENCES customers(customer_id),
order_date TIMESTAMPTZ NOT NULL DEFAULT NOW(),
total NUMERIC(12,2) NOT NULL CHECK (total >= 0),
status VARCHAR(20) NOT NULL
CHECK (status IN ('pending','paid','shipped','delivered','cancelled'))
);

CREATE INDEX idx_orders_customer ON orders(customer_id);
CREATE INDEX idx_orders_status_date ON orders(status, order_date DESC);

-- 2. Тестовые данные
INSERT INTO customers (email, full_name) VALUES
('anna@example.com', 'Анна Смирнова'),
('maxim@example.com', 'Максим Иванов');

INSERT INTO orders (customer_id, total, status)
SELECT
c.customer_id,
(random() * 5000 + 100)::NUMERIC(12,2),
(ARRAY['pending','paid','shipped','delivered'])[(random()*4)::INT + 1]
FROM customers c
CROSS JOIN generate_series(1, 20);

Коротко: наш подход к практическим

Мы не даём вам готовые таблицы не потому, что ленимся.
Мы не даём их потому, что хотим, чтобы вы:

  • научились проектировать базу как профессионалы
  • перестали бояться CREATE TABLE и ALTER TABLE
  • развили чутьё на хорошую/плохую схему
  • научились думать о данных, а не только о запросах
  • получили удовольствие от того, что «всё работает и это сделал я сам»

Если в задаче очень нужна конкретная структура (например, для join’ов или оконных функций) — мы её дадим.
Во всех остальных случаях — творите сами. Это лучший способ вырасти из «я могу писать SELECT» в «я умею проектировать базы».

Удачи и приятного кодинга!
Ваши будущие работодатели уже благодарны вам за этот подход :)

P.S. Если совсем застряли с проектированием схемы — попробуйте другой вариант или обратитесь в github issue, подскажем направление, но не будем писать CREATE TABLE за вас :)