Первая нормальная форма (First Normal Form, 1NF) — это начальная стадия нормализации базы данных, которая накладывает жёсткие ограничения на структуру таблиц. Таблица находится в 1NF, если:
- Все данные являются атомарными. Каждое значение в ячейке таблицы должно быть неделимым. Прощайте, "списки в одной ячейке"! В базе данных этим заниматься нельзя.
- Каждая строка уникальна. То есть таблица должна содержать первичный ключ (Primary Key) или уникальный идентификатор.
- Отсутствуют повторяющиеся группы данных. Значения одной и той же сущности не должны быть представлены в одном и том же столбце.
Говоря проще, представьте, что таблица базы данных — это ваша комната, а атомарные значения — это отдельные предметы: лампа, стол, книга. Если комната захламлена (например, все вещи свалены в кучу), вы не сможете найти лампу или быстро узнать, есть ли у вас резервный стол. Нормализация помогает "расставить всё по полочкам".
Пример нарушения 1NF
Представим, что у нас есть таблица студентов, где мы храним информацию о посещаемых ими курсах:
| student_id | name | courses |
|---|---|---|
| 1 | Maria | "Математика, Физика" |
| 2 | Rob | "Биология, Химия" |
Чем плоха эта структура? Курсы (столбец courses) записаны через запятую в одной ячейке. Это означает, что если мы захотим, например, найти всех студентов, которые изучают физику, то запрос станет кошмаром: придётся проводить сложные преобразования текста. А если один из студентов захочет удалить физику из списка — перед нами встанет новая проблема. Такие данные не являются атомарными, что нарушает основное правило 1NF.
Как привести таблицу к 1NF?
Чтобы решить проблему, мы разделим данные на отдельные строки, где каждое значение таблицы будет атомарным:
| student_id | name | course |
|---|---|---|
| 1 | Maria | Математика |
| 1 | Maria | Физика |
| 2 | Rob | Биология |
| 2 | Rob | Химия |
Теперь всё в порядке. Мы преобразовали нашу таблицу так, чтобы каждое значение в ячейке было неделимым. Это соответствует принципам 1NF.
Подробный пример нарушения 1NF и исправления
Допустим, у нас есть таблица заказов интернет-магазина:
| order_id | customer_name | items |
|---|---|---|
| 1001 | Otto Lin | "Ноутбук, Мышь, Клавиатура" |
| 1002 | Anna Song | "Смартфон, Чехол" |
Очевидно, что здесь items содержит в себе сразу несколько значений через запятую, что нарушает 1NF.
Чтобы привести данные к 1NF, мы будем хранить одну строку на каждый товар в заказе:
| order_id | customer_name | item |
|---|---|---|
| 1001 | Otto Lin | Ноутбук |
| 1001 | Otto Lin | Мышь |
| 1001 | Otto Lin | Клавиатура |
| 1002 | Anna Song | Смартфон |
| 1002 | Anna Song | Чехол |
Теперь структура таблицы соответствует принципам 1NF. Каждый заказ и товар представлены в виде отдельной строки, а значения атомарны.
Добавление первичного ключа
После преобразования таблицы важно добавить уникальный идентификатор (первичный ключ) для каждой строки, чтобы гарантировать их уникальность. В примере выше можно использовать комбинацию order_id и item в качестве составного первичного ключа. Однако в реальной жизни чаще создают отдельное поле id.
| id | order_id | customer_name | item |
|---|---|---|---|
| 1 | 1001 | Otto Lin | Ноутбук |
| 2 | 1001 | Otto Lin | Мышь |
| 3 | 1001 | Otto Lin | Клавиатура |
| 4 | 1002 | Anna Song | Смартфон |
| 5 | 1002 | Anna Song | Чехол |
Практическое задание
У вас есть таблица студентов с предметами, которые они изучают, представленные в одной ячейке:
| student_id | name | subjects |
|---|---|---|
| 1 | Polly | "Математика, Химия" |
| 2 | СPeter | "Физика, Информатика" |
Приведите таблицу к форме, соответствующей 1NF.
После преобразования таблица должна приобрести следующий вид:
| student_id | name | subject |
|---|---|---|
| 1 | Polly | Математика |
| 1 | Polly | Химия |
| 2 | Peter | Физика |
| 2 | Peter | Информатика |
Чаще всего возникающие ошибки при работе с 1NF
Когда вы работаете с базой данных, нарушения 1NF могут проявляться в таких ситуациях:
- Хранение списков или массивов прямо в таблице. Это наиболее частая ошибка.
- Отсутствие уникального идентификатора для строк (первичного ключа). Это делает вашу таблицу уязвимой для дублирующихся данных.
- Использование нескольких столбцов для хранения одинаковой информации. Например, "course_1", "course_2", "course_3" — вместо правильной структуры.
Держите эти моменты в голове, и ваша база данных будет соответствовать первой нормальной форме.
Практическое применение 1NF
В реальных проектах 1NF имеет фундаментальное значение. Например:
- В приложениях для управления клиентами (CRM) данные о клиентах и их действиях должны быть атомарными. Это упрощает анализ и поиск.
- В интернет-магазинах 1NF используется, чтобы эффективно хранить информацию о заказах, товарах и покупателях.
- В банковских системах данные о клиентах, их счетах и транзакциях обязаны быть атомарными, чтобы исключить путаницу между различными операциями.
Соблюдение принципов 1NF помогает проектировать базы данных, которые выдерживают высокие нагрузки и остаются удобными в использовании. Все отлично, но появилось дублирование данных. Поэтому мы переходим ко второй нормальной форме (2NF), где станет понятнее, как разрешать частичные зависимости в таблицах.
Почему важно соблюдать первую нормальную форму (1NF)? Представьте, что вы храните данные в таблице, где в одной ячейке может быть сразу несколько значений — например, список товаров, заказанных покупателем. В таком виде становится сложно обращаться к данным: попытка найти всех, кто заказал "Клавиатуру", превращается в мучение. А если понадобится изменить или удалить часть информации, легко допустить ошибку. Когда данные хранятся в атомарном виде — то есть каждое поле содержит только одно значение — работа с ними становится надёжнее и понятнее. К тому же, такие таблицы проще масштабировать, обновлять и перестраивать при необходимости.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ