В какой момент нормализация данных становится нелепой? - PullRequest
7 голосов
/ 29 марта 2012

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

У меня следующая ситуация:

  1. У меня есть таблица Donor и таблица Recipient. Обе таблицы имеют общую информацию, такую ​​как first_name, last_name, email_address, date_of_birth и т. Д. Обе таблицы, если вы простите мой объектно-ориентированный язык, имеют общий абстрактный тип Person. Возможно, что кто-то, кто в какой-то момент является Recipient, может позже стать Donor посредством пожертвования, поэтому важно, чтобы информация не дублировалась в разных таблицах. Должен ли я выбрать шаблон наследования или просто внешний ключ Donor s и Recipient s для таблицы Person?

  2. Изначально я думал о том, чтобы просто сопоставить свойства, такие как email_address, и свойства уличных адресов непосредственно с вещами, которые в них нуждаются, но тогда может возникнуть вероятность, что у человека будет несколько адресов электронной почты или почтовых адресов (т.е. : дом, работа и т. д.). Это означает, что у нас есть модель, похожая на эту:

    create table person(id int primary key auto increment, ..., 
        default_email_address);
    
    create table email_address(id int primary key auto increment, 
        email varchar(255), name varchar(255), is_default bool, person_id int);
    

    Это немного усложняет ситуацию, как вы можете себе представить. Поле name также включает в себя список значений по умолчанию, а также разрешает пользовательский ввод. Я не могу просто сделать это перечислимым полем, потому что существует вероятность, что кто-то будет иметь много писем, которые можно добавить, которые могут быть разными ... (это точка, в которой я кричу "ЭТО ДАЖЕ СТОИТ ЕГО БОЛЬШЕ !?!? "и разочаровался в проекте)

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

Ответы [ 4 ]

7 голосов
/ 29 марта 2012

В какой момент нормализация данных становится нелепой?

В момент прекращения моделирования фактических потребностей.

Чтобы взять ваши примеры:

  • С таблицами Donor и Recipient, если весьма вероятно, что какой-то один человек станет обоими, тогда имеет смысл разделиться на Person сущность. Если это редко, это не так.

  • В ситуациях email_address и street_address это зависит от того, нужно ли вам хранить кратные числа или нет (каковы ожидания?). Вы можете хранить отдельные версии для каждой бизнес-единицы (например, shipping_address против billing_address).

3 голосов
/ 29 марта 2012

Я думаю, что проблема не в вашей реализации, а скорее в вашем анализе проблемы. Donor и Recipient не первоклассные актеры, они роли актеров. Если вы смоделируете их так, вы получите более чистую модель:

  • У вас будет таблица с адресами и т. Д.
  • У вас также будет таблица адресов с адресами людей
  • У вас также будет таблица person_role с кодом роли (донор, получатель) и другой соответствующей информацией. Вы можете захотеть добавить фантазию и добавить person_donor и person_recipient с внешним ключом в таблицу person.
2 голосов
/ 15 апреля 2012

Краткий ответ : Нормализация никогда не становится нелепой. Большая часть того, что вы делаете, не является нормализацией.

Более длинный ответ

«Наихудшее» (по правде говоря, «лучшее»), которое может сделать большинство дизайнеров, - это получить все таблицы в 5NF. 5NF вовсе не смешно (да, я знаю о 6NF. Я игнорирую это по дидактическим причинам.)

спрашивает, правильно ли я отношусь к попытке планирования для будущего расширения

Это хороший вопрос для себя. Это не имеет ничего общего с нормализацией, хотя. На концептуальном уровне нормализацию - это то, что вы делаете после , когда вы решили, какие атрибуты (столбцы) и данные должны попадать в вашу базу данных. Опытные разработчики баз данных часто «думают в 3NF», выбирая атрибуты, данные и нормализуя все одновременно, более или менее.

Должен ли я выбрать шаблон наследования или просто внешний ключ Таблица «Доноры и получатели персоны»?

Доноры и получатели не разные люди. Доноры - это люди, которые сделали пожертвование. Получатели - это люди, которые что-то получили.

id fullname       don_date    don_amt  recip_date  recip_amt
--
1  Jamie Hubbert  2012-01-13  $20.00
1  Jamie Hubbert  2012-02-13  $17.00
2  Kelly Hawkin   2012-01-13  $50.00
2  Kelly Hawkin   2012-01-13  $20.00
3  Neva Papke                          2012-01-13  $15.00
3  Neva Papke                          2012-02-13  $15.00
2  Kelly Hawkin                        2012-01-13  $10.00
4  Jamie Hubbert  2012-01-13  $10.00   
4  Jamie Hubbert                       2012-02-13  $10.00   

Во время нормализации вы бы идентифицировали эти зависимости. (Для простоты предполагается одно пожертвование на человека в день.)

  • person_id -> person_name
  • person_id -> электронная почта
  • person_id, donation_date -> donation_amount
  • person_id, rece_date -> rece_amount

Нормализуйте до 5NF, и вы получите эти три таблицы.

Persons
--
1  Jamie Hubbert
2  Kelly Hawkin
3  Neva Papke  
4  Jamie Hubbert

Donations
--
1  2012-01-13  $20.00
1  2012-02-13  $17.00
2  2012-01-13  $50.00
2  2012-01-13  $20.00
4  2012-01-13  $10.00   

Receipts (?)
--
3  2012-01-13  $15.00
3  2012-02-13  $15.00
2  2012-01-13  $10.00
4  2012-02-13  $10.00   

Изначально я думал о том, чтобы просто отобразить свойства, такие как свойства email_address и адреса в вещах что они нужны, но тогда может возникнуть вероятность, что человек будет иметь несколько адресов электронной почты или почтовых адресов (например, дома, на работе, и др.).

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

Set A
1  Jamie Hubbert  jhubbert@somedomain.com
4  Jamie Hubbert  jamie.hubbert@this.com

Set B
1  Jamie Hubbert  jhubbert@somedomain.com
1  Jamie Hubbert  jamie@my.com
4  Jamie Hubbert  jamie.hubbert@this.com

В наборе A, person_id-> email. В наборе B это не так. Выбор поддержки данных в наборе A или данных в наборе B является большим решением, и оно сильно влияет на то, что вы в итоге получите после , нормализуя до 5NF. Но решение о том, какой набор поддерживать, не имеет ничего общего с нормализацией.

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

(Случайные имена любезно предоставлены Генератор случайных имен .)

0 голосов
/ 31 марта 2012

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

. Это вовсе не смешная нормализация;на самом деле это довольно распространенная практика.

...