В этом уроке мы разберем вторую нормальную форму реляционной модели, а также два ее требования.
Будем работать с таблицей, которая уже соответствует первой нормальной форме:
order_items
id | first_name | last_name | address | item | price |
---|---|---|---|---|---|
8 | Сергей | Иванов | Москва, ул. Промышленная | утюг | 1000.00 |
2 | Иван | Петров | Самара, ул. Энгельса | кофеварка | 5000.00 |
7 | Виктор | Сидоров | Омск, ул. Дворцовая | утюг | 1000.00 |
4 | Виктор | Сидоров | Омск, ул. Дворцовая | телевизор | 6500.00 |
9 | Сергей | Иванов | Москва, ул. Матросова | ноутбук | 20000.00 |
6 | Сергей | Иванов | Москва, ул. Матросова | ноутбук | 20000.00 |
Вторая нормальная форма
Вторая нормальная форма включает в себя два требования:
- Таблица должна быть в первой нормальной форме
- Все неключевые атрибуты таблицы должны зависеть от первичного ключа
Первое требование уже выполнено, так как в таблице:
- Каждая ячейка хранит только одно значение
- Все данные в одной колонке одного типа
- Каждая запись отличается от других записей
Поэтому разберем подробнее второе требование.
Зависимость от первичного ключа
Зависимость атрибута от первичного ключа — это ситуация, при которой ключ имеет значение, зависимое от конкретного контекста. Предположим, что в таблице, Сергей — это всегда один и тот же человек, который делает заказ на разные адреса. В таком случае видно, что заказ привязан к конкретному пользователю. Это и есть зависимость от первичного ключа. А вот имя пользователя и его фамилия с заказом никак не связано. Оно имеет отношение к самому пользователю.
Согласно второй форме, атрибуты first_name и last_name необходимо вынести в свою таблицу, которая будет отвечать за пользователей:
users
id | first_name | last_name |
---|---|---|
2 | Сергей | Иванов |
3 | Иван | Петров |
5 | Виктор | Сидоров |
В этой таблице всего три записи, потому что у нас три уникальных пользователя. Каждому из этих пользователей присваивается первичный ключ.
Теперь нужно связать таблицу order_items с таблицей users. Делается это через указание первичных ключей в зависимых таблицах:
order_items
id | user_id | address | item | price |
---|---|---|---|---|
8 | 2 | Москва, ул. Промышленная | утюг | 1000.00 |
2 | 3 | Самара, ул. Энгельса | кофеварка | 5000.00 |
7 | 5 | Омск, ул. Дворцовая | утюг | 1000.00 |
4 | 5 | Омск, ул. Дворцовая | телевизор | 6500.00 |
9 | 2 | Москва, ул. Матросова | ноутбук | 20000.00 |
6 | 2 | Москва, ул. Матросова | ноутбук | 20000.00 |
Мы удалили first_name, last_name и добавили user_id. В этом поле хранятся идентификаторы пользователей, а само поле называется внешним или вторичным ключом.
Такую же операцию нужно произвести и с товаром. Вынесем item в свою таблицу:
goods
id | name |
---|---|
50 | утюг |
30 | кофеварка |
20 | телевизор |
33 | ноутбук |
Теперь свяжем эти данные с таблицей order_items:
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 |
Другой пример внешнего ключа в таблице покупателя и города можно схематично показать так:
Внешний ключ — это не ссылка. Таблицы существуют сами по себе, и во внешнем ключе указывается конкретное значение, которое должно совпадать с первичным ключом другой таблицы.
Так выглядит синтаксис определения вторичного ключа:
REFERENCES <название таблицы, на которую смотрим> (<список полей в той таблице, которым соответствуем>)
-- Внешних ключей может быть любое количество: сколько ссылок — столько и ключей
CREATE TABLE orders (
id bigint PRIMARY KEY,
-- Тип внешнего ключа должен быть такой же,
-- как у первичного в той таблице, куда ссылается внешний
user_id bigint REFERENCES users (id),
-- остальные поля
);
Благодаря вторичному ключу поддерживаются гарантии корректности данных. Например, невозможно удалить запись из основной таблицы, если на нее есть ссылки из внешних ключей в другой таблице. Так не получится случайно завести базу в неконсистентное состояние — когда данные ссылаются на несуществующие данные.
Выводы
В этом уроке мы разобрали вторую нормальную форму, ее свойства, а также ее зависимость от внешнего ключа. Осталось изучить третью форму — и у вас будет полное понимание самых распространенных форм в базах данных.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»