Нормализация данных и написание запросов

Я младший. разработчик (5 месяцев на работе), и у меня есть вопрос о нормализации данных. Теперь, как я понимаю, общий принцип нормализации данных заключается в создании СУБД, где избыточность данных сведена к минимуму. В моем проекте Один из людей БД создал БД. У нас есть 50+ таблиц, а таблицы в БД обычно очень фрагментированы, т. е. таблица состоит из двух или трех столбцов, и все. Теперь, когда дело доходит до написания sql-запросов, это стало чем-то второстепенным хлопот, так как каждый запрос включает в себя прочесывание нескольких различных таблиц и объединение их вместе. Мне было интересно, является ли это побочным эффектом нормализации данных? Или это указывает на что-то другое?

Я знаю, что для меня проще всего было бы написать таблицы на основе запросов, которые я должен написать. Это создаст БД с большим количеством избыточных данных, но мне было интересно, есть ли счастливая среда?

просто как постскриптум, я не хочу попадаться как будто я ною о своей работе, но мне действительно интересно узнать больше об этом. Моя рабочая среда не самая дружелюбная, поэтому я не чувствую себя комфортно, задавая этот вопрос своим коллегам. Тем не менее, я был бы признателен за любые мысли, книги, учебники или мнения более опытных людей.

спасибо.

7 ответов


общий принцип нормализации данных заключается в создании СУБД, где избыточность данных сведена к минимуму.

лишь отчасти.

нормализация-это не "избыточность".

речь идет об "аномалиях обновления".

1NF-это правила "не использовать массивы". Нарушение 1NF означает, что строка не является атомарной, но коллекция и независимые обновления в коллекции не сработают хорошо. Там будет замок и ... медлительность.

2NF является правилом" один ключ". Каждая строка имеет только один ключ и все в строке зависит от ключа. Нет никаких зависимостей от часть ключа. Некоторые люди любят говорить о ключах-кандидатах, естественных ключах и внешних ключах; они могут существовать, а могут и не существовать. 2NF удовлетворяется, когда все атрибуты зависят от одного ключа. Если ключ является одноколоночным суррогатным ключом, эта нормальная форма тривиально удовлетворяется.

Если 2NF нарушается, вы получили столбцы, которые зависят от части ключа, но не от всего ключа. Если у вас была таблица с (номером детали, номером редакции) в качестве ключа и атрибутами цвета и веса, где вес зависит от всего ключа, но цвет зависит только от номера детали. У вас есть проблема 2NF, где вы можете обновить некоторые цвета деталей, но не другие, создавая аномалии данных.

3NF-это правило "только ключ". Если вы поместите производные данные в строку и измените производный результат, он не будет соответствовать источнику столбцы. При изменении исходного столбца без обновления производного значения также возникает проблема. Да, триггеры плохой hackaround позволить 3НФ нарушения дизайна. Дело не в этом. Дело в том, чтобы просто определить 3NF и показать, что он предотвращает проблему обновления.

каждый запрос включает в себя прочесывание нескольких различных таблиц и объединение их вместе. Мне было интересно, является ли это побочным эффектом нормализации данных?

Это.


теперь, как я понимаю, генерал принцип нормализации данных создание СУБД, где данные избыточность сведена к минимуму.

Эммм, ОК.

в моем проекте Один из людей DB создал БД. Мы имеем 50 + таблицы, и таблицы в БД обычно очень фрагментированный, т. е. таблица имеет два или три колонки и все.

количество таблиц ничего не сказано о является ли дизайн хорошим или плохим. Некоторые компании нуждаются в одном или двух. Другим нужно больше. Я работал над базами данных в Fortune 500, в которых были тысячи таблиц.

количество столбцов ничего не говорит о том, является ли дизайн хорошим или плохим. И количество столбцов не имеет ничего общего с фрагментацией. Я скажу, что таблицы, которые имеют относительно мало столбцов, обычно являются хорошим знаком. Не всегда хороший знак,но в целом хороший.

теперь, когда он приходит к написанию sql запросы, это стало чем-то вроде незначительные хлопоты, так как каждый запрос включает прочесывание нескольких различных столы и соединение их вместе. Я было интересно, если это на стороне эффект нормализации данных? Или это указывает на что-то еще?

есть две разные, общие причины для этого.

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

  • всегда увеличивает число столы,
  • всегда уменьшает количество столбцов в оригинальной таблице, и
  • иногда требуется соединение для извлечения данные для люди.

Другой распространенной практикой является замена строк идентификаторами. Это не имеет ничего общего с нормализацией. (Нет такой вещи, как"ID number normal form".) Замена строк идентификаторами

  • всегда увеличивает число столы,
  • не изменяет количество столбцов в исходной таблице (если в то же время, что и нормализация),
  • всегда требуется соединение для извлечения данных для людей.

кажется, в других частях этой темы есть некоторая путаница. Я понимаю, что, строго говоря, ни одно из следующих напрямую связано с вопросом OP.

1nf-это принцип "одного значения". Это не имеет ничего общего с строка быть "атомным". В реляционной модели атомные не относится к строкам; он относится к значениям.

"одно значение" означает, что каждый пересечение строки и столбца содержит одно значение. (Другими словами, значение является "атомарным". Но слово атомные имеет некоторые неудачные коннотации, поэтому большинство современных практиков избегают этого.) Это значение не должно быть простым; оно может быть произвольно сложным. Но если у него есть части, которые сами по себе имеют значение, СУБД либо полностью игнорирует эти части, либо предоставляет функции для управления ими. (вы не нужно писать функции для манипулирования части.)

Я думаю, самый простой пример-это дата. Даты имеют части, состоящие из года, месяца и дня. СУБД либо игнорирует эти части (как в 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    home_phone        work_phone    
3          (111) 222-3333    (111) 222-3334
4          (111) 222-3335    (111) 222-3336

2NF-это принцип "всего ключа". Это не имеет ничего общего с количеством ключей; таблица, имеющая столбцы "n", может иметь ключи "n". (См., например, это другой так ответ.) В реляционной модели (и, как следствие, при выполнении упражнений по нормализации), если вы видите слово ключ сам по себе, думаю, "потенциальный ключ".

вместо этого 2NF имеет дело с ключами-кандидатами, которые имеют несколько столбцов. Когда ключ-кандидат имеет несколько столбцов, 2NF требует, чтобы каждый не-простой атрибут функционально зависел от всех столбцов каждого ключа-кандидата, а не только от некоторых столбцов любого ключа-кандидата. (Атрибут non-prime-это атрибут, который не является частью ключа-кандидата.)

следующий пример взят из Википедия запись на 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

хотя это правда, что столбец non-prime current_work_location функционально зависит от первичного ключа {employee, skill}, он также функционально зависит только от части первичного ключа "employee". Эта таблица не в 2NF.

вы не можете уклониться от проблемы 2NF, назначив каждой строке суррогатный ключ. (Первичный ключ-es_id; существует уникальное ограничение на бывший первичный ключ, {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-это принцип "нет транзитивных зависимостей". Это не обязательно имеет какое-либо отношение к производным или вычисленным данным, как вы можете сказать из пример Википедии, адаптировались здесь. (Первичный ключ {турнир, год}. Эта таблица не находится в 3НФ.)

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

две зависимости показывают, что эта таблица имеет транзитивных зависимостей.

  1. The значения в winner_date_of_birth представляется функционально зависит от первичный ключ. Каждое значение первичного ключа определяет одно и только одно значение для winner_date_of_birth. Но. . .
  2. значения в winner_date_of_birth также, как представляется, функционально зависит от победитель. Каждое значение для победителя определяет одно и только одно значение для winner_date_of_birth.

учитывая эти две очевидные функциональные зависимости и понимание того, что слова турнир, победитель и дата рождения значит, мы можем сказать, что

  • победитель - > winner_date_of_birth является функциональная зависимость, и
  • {турнир, год} - > победитель имеет функциональную зависимость, и
  • {турнир, год} -> winner_date_of_birth является транзитивным зависимость.

представления базы данных являются критически важным инструментом в этой дилемме. это отличное введение говорит:

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


Это звучит как нормализация данных, но мне нужно больше знать о схеме, бизнес-кейсе и т. д., Чтобы сделать этот вызов надежным. Если бы у вас был контроль над базой данных, вы могли бы написать посмотреть это представляет общие запросы, которые связывают таблицы. Для повышения производительности можно создать индексируется или материализуется view (имя зависит от платформы базы данных, в данном случае Oracle против Sql Server).

практически любая база данных грунтовка поможет вам вместе с этими понятиями. Если вы используете SQL Server и действительно заинтересованы в получении дополнительной информации, SQL Server книги в Интернете - это отличный ресурс.


наличие большого количества таблиц, безусловно, является признаком хорошо нормализованного дизайна базы данных. Это может быть больно при написании запросов, но гораздо лучше, чем получать данные из синхронизации.

Я иногда пишу отчеты, которые запускаются из базы данных с тысячами таблиц. Каждую ночь у нас есть программа, которая запускает и сбрасывает данные из производственных таблиц в хранилище данных так что мы можем сообщить против него более легко. Таблицы хранилища данных намного меньше нормализовано,и это упрощает написание запросов. Вы можете рассмотреть что-то подобное, если это имеет смысл в вашей ситуации.


Не видя данных, трудно сказать, если ваши данные чрезмерно нормализованы (или просто не нормализованы правильно - распространение полей по нескольким таблицам не означает, что это нормализовано) в целом, хотя, вероятно, вам придется присоединиться к нескольким таблицам, чтобы увидеть полезные данные в хорошо нормализованной базе данных.

вы можете создавать представления, которые объединяют таблицы вместе, а затем вы можете запросить представление. Это, вероятно, поможет при выборе данных.


в хорошо разработанной базе данных соединения, которые вам нужны в ваших запросах, должны быть довольно легко закодированы. Недостатком является многословным в SQL. Оборотные стороны огромны: -

  • последовательная простота обновления таблиц.
  • быстро измените согласно потребностям дела. Хорошо спроектированные DBs обычно могут обрабатывать запросы, которые даже не думали во время оригинального дизайна.
  • быстро разместить новые объекты. Его относительно легко добавлять новые объекты данных и атрибуты хорошо спроектированной базы данных. Это может быть кошмар, включающий, казалось бы, простые изменения в де-нормализованной базе данных.