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

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

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

  1. У меня есть таблица Donor и таблица Recipient. Обе таблицы совместно используют общую информацию, такую ​​как first_name, last_name, email_address, date_of_birth и т. д. Похоже, обе таблицы, если вы извините мой объектно-ориентированный язык, имеют общий абстрактный тип Person. Вполне возможно, что кто-то, кто когда-то был Recipient, позже может стать Donor, сделав пожертвование, поэтому важно, чтобы информация не дублировалась в разных таблицах. Должен ли я выбрать шаблон наследования или просто внешний ключ Donors и Recipients для таблицы 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 также включает в себя список значений по умолчанию, а также возможность пользовательского ввода. Я не могу просто сделать его полем enum, потому что существует вероятность того, что у кого-то будет много электронных писем, которые нужно добавить, и все они могут быть разными... !?!?" и разочароваться в проекте)

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


person Naftuli Kay    schedule 29.03.2012    source источник
comment
В вашем № 2, что было бы альтернативой нормализации данных? Вам почти наверняка не нужны несколько значений для одного поля в одной строке, поэтому я не вижу альтернативы разделению на другую таблицу.   -  person David Thornley    schedule 29.03.2012


Ответы (4)


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

В тот момент, когда он перестает моделировать фактические требования.

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

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

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

person Oded    schedule 29.03.2012
comment
+1, когда он перестает моделировать фактические требования. Зайти слишком далеко в моделировании данных — это то же самое, что зайти слишком далеко при построении ООП-структуры классов. - person N West; 29.03.2012
comment
Основная проблема, которую я пытаюсь предвидеть, — это будущие изменения. Что, если клиент придет и скажет мне, что ему нужно несколько адресов или адресов электронной почты? Как я это вижу, я либо решаю проблему с самого начала, либо переношу SQL-миграцию позже. - person Naftuli Kay; 29.03.2012
comment
@TKKocheran - Вот в чем проблема: I'm trying to anticipate is future changes. Не. Создайте чистую систему, соответствующую текущим требованиям. Когда они меняются, меняйте систему. Вы не можете предвидеть будущее - примите это. - person Oded; 29.03.2012
comment
Кроме того, вы в конечном итоге берете с них плату за нарушение схемы и перестройку, когда даете цитату. Любой другой, кто получит работу по расширению текущей БД, сделает то же самое. - person Chad Harrison; 29.03.2012
comment
Я хотел бы только отметить, что выраженные требования, как правило, не являются реальными требованиями. Часть работы специалиста по базам данных состоит в том, чтобы понять разницу. - person Mike Sherrill 'Cat Recall'; 14.04.2012

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

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

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

Подробный ответ

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

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

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

Должен ли я выбрать шаблон наследования или просто внешние ключи Donors и Recipients для таблицы Person?

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

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, recip_date -> recip_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   

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

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

Set A
1  Jamie Hubbert  [email protected]
4  Jamie Hubbert  [email protected]

Set B
1  Jamie Hubbert  [email protected]
1  Jamie Hubbert  [email protected]
4  Jamie Hubbert  [email protected]

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

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

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

person Mike Sherrill 'Cat Recall'    schedule 15.04.2012

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

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

person FtDRbwLXw6    schedule 31.03.2012