Практика: Нормализация и денормализация
Онлайн редактор кода для 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).