Нормализация базы данных. Бесконечность не предел? - PullRequest
2 голосов
/ 08 декабря 2009

Как точно вы нормализуете пример ниже и какой уровень нормализации соответствует этому примеру?

CREATE TABLE "public"."contact_info" (
  "id" SERIAL, 
  "home_phone" TEXT, 
  "mobile_phone" TEXT, 
  "work_phone" TEXT, 
  "fax_phone" TEXT, 
  "email" TEXT, 
  "line1" TEXT, 
  "line2" TEXT, 
  "city" TEXT, 
  "state_id" INTEGER, 
  "zipcode" TEXT, 
  "preferred_type" TEXT, 
  "first_name" TEXT, 
  "last_name" TEXT,
  CONSTRAINT "contact_info_pkey" PRIMARY KEY("id"), 
  CONSTRAINT "contact_info_fk_state_id" FOREIGN KEY ("state_id")
    REFERENCES "public"."states"("id")
    ON DELETE NO ACTION
    ON UPDATE NO ACTION
    NOT DEFERRABLE
) WITH OIDS;

Следует отметить, что каждая запись может содержать только 0 или 1 номер домашнего, мобильного, рабочего или факсимильного номера. Каждый номер телефона полностью функционально зависит от моего первичного ключа. Из того, что я знаю о нормализации базы данных, я думаю , что соответствует 5NF, но не дает 6NF.

Поскольку определения телефонных номеров заданы в виде камня (нет новых типов телефонных номеров, нет нескольких записей home_phone и т. Д.), Есть ли причина, по которой я хотел бы разделить телефонные номера на отдельное отношение, отслеживаемое (contact_info_id, phone_number Тип)?

Ответы [ 9 ]

2 голосов
/ 08 декабря 2009

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

2 голосов
/ 08 декабря 2009

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

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

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

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

PS. Что такое line1 и line2?

2 голосов
/ 08 декабря 2009

я бы не нормализовал это. Ничего особенного не получится. мы больше не используем базы данных на 8-битных компьютерах с 8 МБ ОЗУ и жестким диском 32 МБ. Это специфично для этого примера. Сложные структуры данных должны быть нормализованы.

Единственный реальный сберегательный символ - это номер телефона, и в среднем его ширина составляет 10 символов, если вы нормализуете его и заменяете его ссылкой на bigint-foreign-reference, вы, кажется, не получаете много, но присоединяются во время выполнения: P и, кроме того, вам нужен int, представляющий тип телефонного номера.

1 голос
/ 08 декабря 2009

Учитывая, что вы говорите:

Следует отметить, что каждая запись может содержать только 0 или 1 номер домашнего, мобильного, рабочего или факсимильного номера.

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

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

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

Однако в другом приложении нам не нужно было это разнообразие: лицензия на программное обеспечение была назначена адресу электронной почты и, следовательно, человеку. Был один почтовый адрес, связанный с покупкой и расширением человека, и это было в значительной степени это. Мы агрегировали лицензии по адресу электронной почты (один человек с несколькими лицензиями), а затем добавили способ объединения людей с несколькими адресами электронной почты (один человек с несколькими адресами электронной почты). Физические адреса были более тесно связаны с платежной информацией.

0 голосов
/ 10 декабря 2009

Можно утверждать, что zipcode определяет (city, state_id), поэтому их следует нормализовать как зависимые столбцы. Однако, если вы не пишете приложение для USPS, это обычно не делается. То же самое с вашим первоначальным вопросом - наличие 4 телефонных записей не слишком больно, я бы сохранил дизайн таким образом.

0 голосов
/ 08 декабря 2009

Я бы разделил телефонные номера - по всем причинам, упомянутым другими, ПЛЮС - если ваши пользователи когда-нибудь захотят выполнить поиск по номеру телефона, было бы реальным хлопотом написать sql с таким дизайном (если вы захотите для поиска по нескольким типам телефонных номеров).

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

0 голосов
/ 08 декабря 2009

Почему бы не поставить отдельную таблицу с 3 полями: id , type_of и число . Тогда вы могли бы избавиться от ваших * _phone вещи. Что-то вроде:

id      type_of      number
1       home         222 11 22
1       work         312 12 12
2       mobile       345 23 23
2       home         233 65 23
2       work         945 30 19

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

0 голосов
/ 08 декабря 2009

есть ли причина, по которой я хотел бы разделить телефонные номера на отдельную связь, отслеживаемую (contact_info_id, номер_файла, тип)?

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

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

0 голосов
/ 08 декабря 2009

Я хотел бы отметить одну вещь: использование столбцов TEXT - пустая трата времени, почему бы не использовать VARCHAR?

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

...