Ответ
Третья нормальная форма (3NF) — это правило проектирования реляционных баз данных, направленное на устранение избыточности данных и аномалий при обновлении. Таблица находится в 3NF, если:
- Она находится во второй нормальной форме (2NF) (все неключевые атрибуты полностью зависят от первичного ключа).
- Отсутствуют транзитивные зависимости: ни один неключевой атрибут не зависит от другого неключевого атрибута. Каждый неключевой атрибут должен зависеть только от первичного ключа.
Пример нарушения 3NF:
Допустим, у нас есть таблица Заказы (Orders): |
OrderID (PK) | CustomerID | CustomerName | CustomerEmail |
|---|---|---|---|---|
| 1 | 101 | Иван Петров | ivan@example.com | |
| 2 | 101 | Иван Петров | ivan@example.com | |
| 3 | 102 | Мария Сидорова | maria@example.com |
Здесь CustomerName и CustomerEmail зависят не от OrderID, а от CustomerID. Это транзитивная зависимость. При смене email клиента пришлось бы обновлять все его заказы, что ведет к аномалии обновления и избыточности.
Приведение к 3NF: Нужно разделить таблицу, вынеся информацию о клиенте в отдельную сущность.
Таблица Заказы (Orders): |
OrderID (PK) | CustomerID (FK) |
|---|---|---|
| 1 | 101 | |
| 2 | 101 | |
| 3 | 102 |
Таблица Клиенты (Customers): |
CustomerID (PK) | CustomerName | CustomerEmail |
|---|---|---|---|
| 101 | Иван Петров | ivan@example.com | |
| 102 | Мария Сидорова | maria@example.com |
Теперь данные о клиенте хранятся в одном месте. В контексте Node.js при работе, например, с ORM Sequelize, это будет отражено в двух связанных моделях с отношением hasMany / belongsTo.
Ответ 18+ 🔞
А, слушай, про третью нормальную форму! Ну это ж классика, ёпта. Сидишь такой, проектируешь базу, думаешь — ну чё, вроде табличка, поля есть, вроде норм. А потом бац — и начинаются аномалии, как в плохом триллере. Данные дублируются, обновлять их — пиздец, терпения ноль ебать.
Так вот, чтобы не было этой мути, умные дядьки придумали 3NF. Суть проще пареной репы, если не усложнять. Таблица в третьей нормальной форме, если:
- Она уже во второй (2NF) — то есть все неключевые поля зависят от всего первичного ключа, а не от его кусочка. Это база.
- И тут главное: нет транзитивных зависимостей. Это когда какой-то неключевой атрибут зависит не от ключа напрямую, а от другого такого же неключевого поля. Получается цепочка: ключ → поле А → поле Б. Вот это — пизда рулю. От этого и надо избавляться.
Смотри, как это бывает на практике:
Допустим, делаем таблицу Заказы. Накосячили, как обычно в первом приближении.
Orders
| OrderID (PK) | CustomerID | CustomerName | CustomerEmail |
|--------------|------------|--------------|---------------------|
| 1 | 101 | Иван Петров | ivan@example.com |
| 2 | 101 | Иван Петров | ivan@example.com |
| 3 | 102 | Мария Сидорова | maria@example.com |
Смотри, в чём подвох. OrderID — ключ. А имя клиента и его почта нихуя от номера заказа не зависят. Они привязаны к CustomerID. Получается, CustomerName зависит от CustomerID, а тот уже от OrderID. Это и есть та самая транзитивная зависимость, хитрая жопа.
И что в итоге? Если Иван Петров сменит почту, тебе придётся бегать и латать её в каждой его строчке заказа. Овердохуища работы, и если забудешь одну — данные поехали, доверия ебать ноль. Плюс дублирование — почта Ивана хранится в двух местах. Зачем? Манда с ушами получается.
Как лечить? Да ебушки-воробушки, всё гениальное просто — режем таблицу на две.
Таблица Заказы (Orders):
| OrderID (PK) | CustomerID (FK) |
|--------------|-----------------|
| 1 | 101 |
| 2 | 101 |
| 3 | 102 |
Таблица Клиенты (Customers):
| CustomerID (PK) | CustomerName | CustomerEmail |
|-----------------|--------------|---------------------|
| 101 | Иван Петров | ivan@example.com |
| 102 | Мария Сидорова | maria@example.com |
Вот теперь красота. Данные о клиенте в одном-единственном месте. Поменял почту в Customers — и она автоматом актуальна для всех его заказов. В Node.js с тем же Sequelize это будет две модели: Order и Customer, связанные через Customer.hasMany(Order) и Order.belongsTo(Customer). Чисто, логично, и аномалий обновления — как не бывало. В общем, не пренебрегай нормализацией, а то потом сам от себя охуеешь, когда начнётся ад с данными.