Нормалізація - розкладання даних по таблицях так, щоб кожен факт зберігався в одному місці. Мета - уникнути аномалій: коли зміну доводиться вносити в кількох місцях і одне з них забувають.
Приклад проблеми:
orders: id | customer_name | customer_email | product | price
1 | Оля | olia@x.com | Книга | 300
2 | Оля | olia@x.com | Ручка | 50
Оля змінила email - треба оновити всі її замовлення. Пропустили одне - дані суперечать одне одному.
Нормальні форми (основні три):
- 1НФ - у кожній клітинці одне атомарне значення; немає повторюваних груп («product1, product2, product3» чи список через кому в одній колонці).
- 2НФ - 1НФ, і кожна неключова колонка залежить від усього складеного ключа, а не від частини. У таблиці
(order_id, product_id, product_name, qty)назва товару залежить лише відproduct_id- її місце в таблиці товарів. - 3НФ - 2НФ, і неключові колонки не залежать одна від одної (немає транзитивних залежностей).
orders (id, customer_id, customer_email)- email залежить від клієнта, а не від замовлення.
Нормалізована схема:
customers: id | name | email
products: id | name | price
orders: id | customer_id | created_at
order_items: order_id | product_id | quantity | price_at_purchase
Зверніть увагу на price_at_purchase: ціна в момент покупки - окремий факт, а не дублювання. Якщо завтра ціна товару зміниться, старе замовлення не має змінитися.
Практичне правило: проєктувати в 3НФ за замовчуванням і свідомо денормалізувати там, де виміряно, що це потрібно для швидкодії. Вищі форми (BCNF, 4НФ, 5НФ) у прикладних застосунках потрібні рідко.