Теперь, насколько я понимаю, общий принцип нормализации данных заключается в создании СУБД, в которой избыточность данных сведена к минимуму.
Ммм, ок.
В моем проекте один из сотрудников БД создал БД.У нас есть более 50 таблиц, и таблицы в БД обычно очень фрагментированы, т.е.таблица имеет два или три столбца и все.
Количество таблиц ничего не говорит о том, хорош дизайн или плох.Некоторым предприятиям нужен один или два.Другим нужно больше.Я работал над базами данных в Fortune 500, которые имели тысячи таблиц.
Количество столбцов ничего не говорит о том, хорош дизайн или плох.А количество столбцов не имеет ничего общего с фрагментацией.Я скажу, что таблицы с относительно небольшим количеством столбцов, как правило, являются хорошим знаком.Не всегда хороший знак, но обычно хороший знак.
Теперь, когда речь заходит о написании sql-запросов, это становится чем-то небольшим, так как каждый запрос включает в себя прохождение нескольких разных таблиц и объединениеих вместе.Мне было интересно, если это побочный эффект нормализации данных?Или это указывает на что-то еще?
Для этого есть две разные общие причины.
Когда вы нормализуете таблицу, вы уменьшаете избыточность (и повышаете целостность данных), идентифицируяфункциональные зависимости, выделение функционально зависимых столбцов в одной или нескольких новых таблицах и удаление их из исходной таблицы.Таким образом, нормализация таблицы в смысле перехода от более низкой нормальной формы к более высокой нормальной форме
- всегда увеличивает количество таблиц,
- всегда уменьшает количество столбцов висходная таблица и
- иногда требуется объединение для извлечения данных для людей.
Еще одна распространенная практика - заменить строки на идентификаторы.Это не имеет ничего общего с нормализацией.(Не существует такого понятия, как «нормальная форма номера идентификатора».) Замена строк с номерами идентификаторов
- всегда увеличивает количество таблиц,
- не меняет количество столбцов висходная таблица (если не сделано одновременно с нормализацией),
- всегда требуется соединение для извлечения данных для людей.
Кажется,быть некоторая путаница в других частях этой темы.Я понимаю, что, строго говоря, ни одно из следующих положений не имеет отношения непосредственно к вопросу ОП.
1NF является принципом "единого значения".Это не имеет ничего общего с строкой , являющейся "атомарной".В реляционной модели atomic не относится к строкам;это относится к ценностям.
«Одно значение» означает, что каждое пересечение строки и столбца содержит одно значение.(Другими словами, значение «атомное». Но слово атомное имеет некоторые неудачные коннотации, поэтому большинство современных практиков избегают его.) Это значение не обязательно должно быть простым;это может быть сколь угодно сложным.Но если у него есть части, которые сами по себе имеют значение, dbms либо полностью игнорирует эти части, либо предоставляет функции для управления ими.( Вам не нужно писать функции для управления деталями.)
Я думаю, что самый простой пример - это дата.Даты имеют части, состоящие из года, месяца и дня.DBMS либо игнорирует эти части (как в SELECT CURRENT_DATE
), либо предоставляет функции для управления ими (как в SELECT EXTRACT(YEAR FROM CURRENT_DATE)
).
Попытки уклониться от принципа «одно значение» приводят к следствию:принцип "без повторяющихся групп".
Повторяющаяся группа включает несколько значений из одного домена, причем все значения имеют одинаковое значение.Таким образом, таблица, подобная следующей, является примером одного вида повторяющейся группы.(Существуют и другие виды.) Значения для «phone_1» и «phone_2» происходят из одного и того же домена, и имеют одинаковое значение - у пользователя n есть номера телефонов (phone_1 и phone_2).(Первичный ключ - "user_id".)
user_id phone_1 phone_2
1 (111) 222-3333 (111) 222-3334
2 (111) 222-3335 (111) 222-3336
Но следующая таблица, хотя и очень похожа, не имеет повторяющейся группы.Значения происходят из одного домена, но они не имеют одинакового значения.(Первичный ключ - "user_id".)
user_id home_phone work_phone
3 (111) 222-3333 (111) 222-3334
4 (111) 222-3335 (111) 222-3336
2NF - это принцип "полного ключа".Это не имеет никакого отношения к количеству ключей;таблица с n столбцами может иметь n ключей.(См., Например, этот другой ответ SO .) В реляционной модели (и, соответственно, при выполнении упражнений по нормализации), если вы видите слово key byсам подумайте «ключ-кандидат».
Вместо этого 2NF имеет отношение к ключам-кандидатам, которые имеют несколько столбцов.Когда ключ-кандидат имеет несколько столбцов, 2NF требует, чтобы каждый непростой атрибут был функционально зависимым от всех столбцов каждого ключа-кандидата, а не только от некоторых столбцов любого ключа-кандидата.(Непростой атрибут - это атрибут, который не является частью ключа-кандидата.)
Следующий пример адаптирован из записи Википедии в 2nf .(Первичный ключ - {employee, skill}.)
Table: employee_skills
employee skill current_work_location
--
Jones Typing 114 Main Street
Jones Shorthand 114 Main Street
Jones Whittling 114 Main Street
Bravo Light Cleaning 73 Industrial Way
Ellis Alchemy 73 Industrial Way
Ellis Flying 73 Industrial Way
Harrison Light Cleaning 73 Industrial Way
Несмотря на то, что столбец current_work_location, не являющийся простым, функционально зависит от первичного ключа {employee, skill}, он также функционально зависит только от частипервичного ключа, «сотрудник».Эта таблица не в 2NF.
Вы не можете избежать проблемы 2NF, присваивая каждой строке суррогатный ключ.(Первичный ключ - es_id; есть ограничение UNIQUE на прежний первичный ключ, {employee, skill}).
Table: employee_skills
es_id employee skill current_work_location
--
1 Jones Typing 114 Main Street
2 Jones Shorthand 114 Main Street
3 Jones Whittling 114 Main Street
4 Bravo Light Cleaning 73 Industrial Way
5 Ellis Alchemy 73 Industrial Way
6 Ellis Flying 73 Industrial Way
7 Harrison Light Cleaning 73 Industrial Way
Должно быть очевидно, что добавление идентификатора не привело к удалению частичной зависимости employee->current_work_location
.Без удаления частичной зависимости эта таблица все еще не находится в 2NF.
3NF - это принцип "без транзитивных зависимостей".Это не обязательно имеет отношение к производным или вычисленным данным, как вы можете сказать из примера Википедии , адаптированного здесь.(Первичный ключ - {турнир, год}. Эта таблица не в 3NF.)
Table: tournament_winners
tournament year winner winner_date_of_birth
--
Indiana Invitational 1998 Al Fredrickson 21 July 1975
Cleveland Open 1999 Bob Albertson 28 September 1968
Des Moines Masters 1999 Al Fredrickson 21 July 1975
Indiana Invitational 1999 Chip Masterson 14 March 1977
Две зависимости показывают, что эта таблица имеет транзитивную зависимость.
- Значения в winner_date_of_birth функционально зависят от первичного ключа.Каждое значение первичного ключа определяет одно и только одно значение для winner_date_of_birth.Но .,.
- Значения в winner_date_of_birth также, по-видимому, функционально зависят от победителя.Каждое значение для победителя определяет одно и только одно значение для winner_date_of_birth.
Учитывая эти две очевидные функциональные зависимости и понимание того, что слова турнир , победитель и дата рождения означает, что можно сказать, что
- winner -> winner_date_of_birth является функциональной зависимостью, а
- {турнир, год} -> победительявляется функциональной зависимостью, а
- {турнир, год} -> winner_date_of_birth является транзитивной зависимостью.