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

Практика: Нормализация и денормализация


Онлайн редактор кода для Go

Здесь вы можете попробовать свои силы в программировании на языке Go. Для этого мы предоставляем вам онлайн редактор кода, в котором вы можете написать свой код и запустить его.


❗️ При обновлении страницы код пропадёт, по этому, сохраните свой код куда-нибудь, если он важный.

Задание 1 — Приведение к нормальным формам

Задание 1: Приведение неудовлетворительной схемы к 1NF–3NF

⏱️ Примерное время: 15-30 минут

Возьми не нормализованную таблицу и приведи её к 1NF, затем к 2NF, затем к 3NF.


Требования:

  • покажи исходную "плохую" таблицу (CREATE TABLE + 2–3 INSERT)
  • приведи к 1NF (убрать повторяющиеся группы, сделать атомарные значения)
  • приведи к 2NF (убрать частичные зависимости)
  • приведи к 3NF (убрать транзитивные зависимости)
  • добавь первичные и внешние ключи
  • кратко напиши, какие аномалии устраняются на каждом шаге

Пример:

-- Исходная (плохо)
CREATE TABLE bad_orders (
order_id SERIAL PRIMARY KEY,
customer_name VARCHAR(100),
customer_phone VARCHAR(20),
products TEXT, -- "Ноутбук, Мышь, Клавиатура"
quantities TEXT -- "1,2,1"
);

-- 1NF
CREATE TABLE orders_1nf (...);
CREATE TABLE order_items_1nf (...);

-- 2NF
CREATE TABLE products (...);
CREATE TABLE orders_2nf (...);
CREATE TABLE order_items_2nf (...);

-- 3NF
CREATE TABLE customers (...);
...

Задание 2 — Выбор ключей и ограничений

Задание 2: Суррогатные vs естественные ключи + ограничения

⏱️ Примерное время: 20-35 минут

Выбери подходящий первичный ключ и добавь важные ограничения.


Требования:

  • обоснуй выбор: SERIAL / UUID / естественный ключ / составной ключ
  • добавь минимум 3–4 CHECK / NOT NULL / UNIQUE ограничения
  • добавь внешние ключи где нужно
  • напиши 1–2 примера INSERT, которые должны провалиться из-за ограничений

Пример:

CREATE TABLE users (
user_id BIGSERIAL PRIMARY KEY, -- суррогатный
email VARCHAR(255) UNIQUE NOT NULL,
phone VARCHAR(20) UNIQUE,
full_name VARCHAR(100) NOT NULL,
birth_date DATE CHECK (birth_date < CURRENT_DATE - INTERVAL '18 years'),
created_at TIMESTAMPTZ DEFAULT NOW()
);

Задание 3 — Денормализация для скорости

Задание 3: Денормализация + триггеры / matview

⏱️ Примерное время: 30-50 минут

Добавь денормализованные поля / представления для ускорения чтения.


Требования:

  • создай триггер(ы) для автоматического обновления денормализованных полей
  • или создай материализованное представление + покажи REFRESH
  • сравни запрос с JOIN и запрос с денормализованным полем (EXPLAIN ANALYZE можно описать словами)

Пример:

ALTER TABLE orders ADD COLUMN items_count INTEGER DEFAULT 0;

CREATE TRIGGER update_items_count
AFTER INSERT OR UPDATE OR DELETE ON order_items
FOR EACH ROW EXECUTE FUNCTION update_order_items_count();

Задание 4 — Антипаттерны и рефакторинг

Задание 4: Поиск и исправление антипаттернов

⏱️ Примерное время: 40-70 минут

Найди проблемы в предложенной схеме и предложи улучшения.


Требования:

  • опиши 3–5 проблем (аномалии, производительность, целостность)
  • предложи нормализованную / гибридную схему
  • добавь ограничения, индексы, комментарии
  • обоснуй, где денормализация всё-таки оправдана

Пример:

-- Плохо:
CREATE TABLE mega_orders (... 40 колонок ...);

-- Хорошо:
CREATE TABLE customers (...);
CREATE TABLE orders (...);
CREATE TABLE order_items (...);
-- + материализованное представление для отчётов

Задание 5 — Итоговое: Проектирование схемы интернет-магазина

Задание 5: Полноценная схема магазина (итоговое)

⏱️ Примерное время: 90-180 минут

Спроектируй схему интернет-магазина от начала до конца.


Требования:

  • минимум 6–10 таблиц
  • нормализованная основа (1–3NF)
  • осознанная денормализация (2–4 поля / matview / кэш)
  • первичные / внешние ключи, CHECK, UNIQUE
  • индексы на самых частых операциях
  • комментарии к таблицам и ключевым колонкам
  • 1–2 триггера или функции
  • 1 материализованное представление
  • краткое описание компромиссов (где и почему денормализовано)

Это задание можно использовать как полноценный кейс для портфолио или собеседования.

подсказка

Нормализация — это про безопасность и простоту поддержки.
Денормализация — это про скорость чтения и удобство запросов.
Золотое правило: нормализуй до тех пор, пока производительность чтения тебя устраивает.
Как только SELECT начинает тормозить — начинай думать о денормализации, но всегда с контролем консистентности (триггеры, matview, jobs).