В этом уроке мы разберем третью нормальную форму реляционной модели, а также ее требования.
Будем работать с текущей структурой:
users
id | first_name | last_name |
---|---|---|
2 | Сергей | Иванов |
3 | Иван | Петров |
5 | Виктор | Сидоров |
goods
id | name |
---|---|
50 | утюг |
30 | кофеварка |
20 | телевизор |
33 | ноутбук |
order_items
id | user_id | address | good_id | price |
---|---|---|---|---|
8 | 2 | Москва, ул. Промышленная | 50 | 1000.00 |
2 | 3 | Самара, ул. Энгельса | 30 | 5000.00 |
7 | 5 | Омск, ул. Дворцовая | 50 | 1000.00 |
4 | 5 | Омск, ул. Дворцовая | 20 | 6500.00 |
9 | 2 | Москва, ул. Матросова | 33 | 20000.00 |
6 | 2 | Москва, ул. Матросова | 33 | 20000.00 |
Третья нормальная форма
Третья нормальная форма включает в себя два пункта:
- Таблица должна быть во второй нормальной форме
- Все колонки в таблице зависят от первичного ключа и не зависят друг от друга
Первое требование уже выполнено, так как:
- Таблица соблюдает требования первой нормальной формы
- Все неключевые атрибуты таблицы зависят от первичного ключа
Поэтому разберем подробнее второе требование.
Зависимость колонок от первичного ключа, но не друг от друга
Стоимость заказа зависит от цены товара. При этом цена товара зависит от самого товара, то есть от good_id. Чтобы привести таблицу к третьей форме, нужно вынести цену в товар:
goods
id | name | price |
---|---|---|
50 | утюг | 1000.00 |
30 | кофеварка | 5000.00 |
20 | телевизор | 6500.00 |
33 | ноутбук | 20000.00 |
Наша таблица приобретает такой вид:
order_items
id | user_id | address | good_id |
---|---|---|---|
8 | 2 | Москва, ул. Промышленная | 50 |
2 | 3 | Самара, ул. Энгельса | 30 |
7 | 5 | Омск, ул. Дворцовая | 50 |
4 | 5 | Омск, ул. Дворцовая | 20 |
9 | 2 | Москва, ул. Матросова | 33 |
6 | 2 | Москва, ул. Матросова | 33 |
С одной стороны, мы выполнили большую часть необходимой нормализации, с другой — новая структура имеет большой недостаток. Цена товара — вещь изменяемая, а вот стоимость покупки, которую мы совершили в прошлом – нет. Когда изменяется цена товара, изменится стоимость всех совершенных покупок, в которые входил данный товар. С точки зрения бухгалтерии и истории покупок это недопустимо.
Это значит, что цена товара должна копироваться в таблицу order_items. Но и в таблице goods она тоже нужна. В первую очередь для вывода на сайте на витрине.
Адрес тоже зависит от пользователя, но более сложным образом. У одного пользователя может быть несколько адресов. Если учитывать все, что мы говорили про нормальные формы, перенести адреса в таблицу пользователей нельзя. Мы не можем хранить несколько значений в одной колонке и не можем дублировать записи, так как нарушится уникальность первичного ключа.
Правильное решение – завести под адреса собственную таблицу. В ней адрес будет связан с пользователем, а вместо поля address в таблице заказов появится поле user_address_id.
Выводы
В этом уроке мы изучили третью нормальную форму. Теперь ваших знаний о формах в реляционной модели достаточно, чтобы работать с самыми распространенными задачами в базах данных.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»