Здравствуйте! Сегодня: Чт, 22 Окт 2020, Ваш IP: 3.238.62.144 Войти через loginza
 
Вход | Регистрация | Забыли пароль?
Мой Kbyte.Ru
> Список форумов Kbyte.Ru - - Базы данных
+ Создать новую тему Страница: 1
Тема: Нормализация · +  +  дата добавления: 04.04.2013 / 08:05
Автор темы:
rusiko
rusiko
тем: 104 / ответов: 25 / благодарностей: 0 / репутация: 3
ответов: 25
создал(а) тем: 104


Привет всем. Скажите пожайлуста что такое первая, вторая и третья нормальные формы в SQL. В интернете я нашел много статей на эту тему, но почти все они одинаково излагают эту тему. Кто-нибудь может мне объяснить это как-то по своему, как-то понятно. Спасибо заранее.
Технологии: Microsoft SQL Server
 
Ответ # 1 # · +  +  · в избранномx1 дата добавления: 04.04.2013 / 10:48
Автор ответа:
Алексей Немиро
Алексей Немиро
тем: 534 / ответов: 5130 / благодарностей: 325 / репутация: 211
Чашка Kbyte.Ru>>
Url: aleksey.nemiro.ru
Icq: 261779681
Skype: alekseynemiro
ответов: 5130
создал(а) тем: 534


Сложная тема :)

Само по себе, нормализация - это приведение базы в идеальный вид по мнению Кристофера Дейта, который внес свой вклад в развитие релаксационных баз данных, в коих число входит и SQL Server.

В первой форме необходимо, чтобы данные были полностью уникальными. Чтобы не было дубликатов данных, в том числе: строк с полностью идентичными данными, колонок с одинаковыми названиями.

Важный момент, нужно чтобы не было логических дубликатов данных.

Остальные формы зависят от первой, но стремятся еще более максимально объединить одинаковую информацию, чтобы уменьшить объем лишних данных (дубликатов).

Например, есть холодильник. Требуется, чтобы на первой полке лежали только красные яблоки, на второй - желтые, на третей - зеленые.
Неправильная логика хранения яблок может быть следующей:
Первая полка   | Вторая полка  | Третья полка 
------------------------------------------------
Красное яблоко | Желтое яблоко | Зеленое яблоко
Почему логика неправильная, думаю это очевидно. В данной структуре присутствует жесткая привязка яблок к полкам. Стоит изменить количество яблок или добавить новую полку, структура холодильника сильно изменится, станет не удобной, сложной, и будет требоваться много времени, чтобы найти что-то в таком холодильнике, не говоря уже о том, само изменение структуры процесс достаточно дорой.
Первая полка   | Вторая полка  | Третья полка 
------------------------------------------------
Красное яблоко | Желтое яблоко | Зеленое яблоко
               | Желтое яблоко | Зеленое яблоко
               | Желтое яблоко | Зеленое яблоко
               | Желтое яблоко |  
               | Желтое яблоко |
               | Желтое яблоко | 
               | Желтое яблоко |
Представим, что в холодильнике хранится сто тонн яблок. Если понадобится добавить новую полку, то придется разгрузить холодильник (а там ведь сто тонн яблок), добавить полку и загрузить обратно яблоки (напомню, что их там сто тонн). В реальных условиях, изменение структуры базы данных, размер которой несколько десятков, а то и сотен, гигабайт может занять множество СУТОК. Даже самые простые действия в изменении структуры базы данных могут сделать базу недоступной для работы, что при коммерческом использовании может стать серьезной проблемой.

Все полки в холодильнике - это по сути один логический объект. Делая для каждой полки отдельную колонку в таблице - это дубликаты, что не соответствует первой нормальной форме. Происходит расширение таблицы по горизонтали, что само по себе плохо (хотя иногда может и не быть другого варианта, но это уже другой вопрос).

В идеале структура должна быть такой:
Полка        | Яблоко
-----------------------------
Первая полка | Красное яблоко 
-----------------------------
Вторая полка | Желтое яблоко 
-----------------------------
Третья полка | Зеленое яблоко
Т.е. расширение данных будет происходить по вертикали, а не горизонтали. Это лучше, т.к. не нужно будет менять структуру таблицы.

Яблок может быть множество, если они будут хранить в куче, то сложно будет выбрать конкретное яблоко. Например:
Полка        | Яблоко
-----------------------------
Первая полка | Красное яблоко 
-----------------------------
Вторая полка | Желтое яблоко 
             | Желтое яблоко
             | Желтое яблоко
-----------------------------
Третья полка | Зеленое яблоко
             | Зеленое яблоко
             | Зеленое яблоко
             | Зеленое яблоко
             | Зеленое яблоко
Попробуй-ка выбрать второе яблоко со второй полки! А если их там сотни, тысячи, миллионы?
Происходит группировка логически идентичных объектов в ячейке данных, т.е. не соответствует первой нормальной форме.
Яблоки должны быть разделены:
Полка        | Яблоко
-----------------------------
Первая полка | Красное яблоко 
-----------------------------
Вторая полка | Желтое яблоко 
-----------------------------
Вторая полка | Желтое яблоко
-----------------------------
Вторая полка | Желтое яблоко
-----------------------------
Третья полка | Зеленое яблоко
-----------------------------
Третья полка | Зеленое яблоко
-----------------------------
Третья полка | Зеленое яблоко
-----------------------------
Третья полка | Зеленое яблоко
-----------------------------
Третья полка | Зеленое яблоко
Однако яблоки не уникальные. Сделать их уникальными можно добавив новое свойство. У нас уже есть два свойство - цвет и тип продукта (яблоко):
Полка        | Продукт | Цвет
---------------------------------
Первая полка | Яблоко  | Красный
---------------------------------
Вторая полка | Яблоко  | Желтый
---------------------------------
Третья полка | Яблоко  | Зеленый
Чтобы продукты были уникальными, им можно присвоить порядковый номер:
Полка        | Номер продукта | Продукт | Цвет
---------------------------------------------------
Первая полка | 1              | Яблоко  | Красный
---------------------------------------------------
Вторая полка | 2              | Яблоко  | Желтый
---------------------------------------------------
Вторая полка | 3              | Яблоко  | Желтый
---------------------------------------------------
Вторая полка | 4              | Яблоко  | Желтый
---------------------------------------------------
Третья полка | 5              | Яблоко  | Зеленый
---------------------------------------------------
Третья полка | 6              | Яблоко  | Зеленый
---------------------------------------------------
Третья полка | 7              | Яблоко  | Зеленый
---------------------------------------------------
Третья полка | 8              | Яблоко  | Зеленый
---------------------------------------------------
Третья полка | 9              | Яблоко  | Зеленый
Аналогично можно сделать с полками, чтобы не было дубликатов:
Номер полки  | Название полки 
---------------------------------
1            | Первая полка 
---------------------------------
2            | Вторая полка 
---------------------------------
3            | Третья полка
Холодильник:
Номер полки  | Номер продукта | Продукт | Цвет
---------------------------------------------------
1            | 1              | Яблоко  | Красный
---------------------------------------------------
2            | 2              | Яблоко  | Желтый
---------------------------------------------------
2            | 3              | Яблоко  | Желтый
---------------------------------------------------
3            | 4              | Яблоко  | Желтый
---------------------------------------------------
3            | 5              | Яблоко  | Зеленый
---------------------------------------------------
3            | 6              | Яблоко  | Зеленый
---------------------------------------------------
3            | 7              | Яблоко  | Зеленый
---------------------------------------------------
3            | 8              | Яблоко  | Зеленый
---------------------------------------------------
3            | 9              | Яблоко  | Зеленый
Аналогично можно сделать с продуктами и цветом:
Номер типа продукта  | Название продукта
---------------------------------
1                    | Яблоко 
Номер цвета     | Название цвета
---------------------------------
1               | Красный
---------------------------------
2               | Желтый
---------------------------------
3               | Красный
В конечном итоге, холодильник соответствующий идеологии нормализации будет таким:
Номер полки  | Номер продукта | Номер типа продукта | Номер цвета
-------------------------------------------------------------------
1            | 1              | 1                   | 1
-------------------------------------------------------------------
2            | 2              | 1                   | 2
-------------------------------------------------------------------
2            | 3              | 1                   | 2
-------------------------------------------------------------------
3            | 4              | 1                   | 2
-------------------------------------------------------------------
3            | 5              | 1                   | 2
-------------------------------------------------------------------
3            | 6              | 1                   | 3
-------------------------------------------------------------------
3            | 7              | 1                   | 3
-------------------------------------------------------------------
3            | 8              | 1                   | 3
-------------------------------------------------------------------
3            | 9              | 1                   | 3
В таком холодильник можно легко добавить новые полки, или убрать старые. Расширить ассортимент продуктов, цветов. Поменять расположение продуктов, поменять сами продукты и любые их свойства.

По сути, каждый программист, с получением опыта, стремится к подобной структуре.

Однако, такая, вертикальная структура имеет свои подводные камни, если перестараться, может получиться "как всегда". Нужно учитывать ресурсы и реальные возможности при проектировании базы данных. Учитывать потенциальные объем, варианты расширения. Если сделать полностью гибкую базу и эта гибкость окажется невостребованной, то это в конечном итоге может негативно отразиться на производительности. Также нужно умело использовать гибкость базы при работе с ней. Стараться делать меньше JOIN-ов (избыток JOIN-ов в вертикальной структуре может серьезно тормознуть базу), в меру создавать индексы (если перестараться, опять же можно снизить производительность).

Нужно стремиться упрощать все, ибо простота - это есть совершенство.
 
Страница: 1 + Создать новую тему