Лучший способ моделировать адрес клиента <-> - PullRequest
20 голосов
/ 15 марта 2009

Каждый Customer имеет физический адрес и дополнительный почтовый адрес. Как вы предпочитаете моделировать это?

Опция 1. Customer имеет внешний ключ для Address

   Customer   (id, phys_address_id, mail_address_id)
   Address    (id, street, city, etc.)

Вариант 2. Customer имеет отношение один ко многим к Address, которое содержит поле описать тип адреса

   Customer   (id)
   Address    (id, customer_id, address_type, street, city, etc.)

Вариант 3. Информация об адресе нормализуется и сохраняется в Customer

   Customer   (id, phys_street, phys_city, etc. mail_street, mail_city, etc.)

Одна из моих главных целей - упростить объектно-реляционные отображения, поэтому я склоняюсь к первому подходу. Что ты думаешь?

Ответы [ 12 ]

10 голосов
/ 15 марта 2009

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

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

   Customer   (id, phys_address_id)
   Cust_address_type (cust_id, mail_address_id, address_type, start_date, end_date)
   Address    (id, street, city, etc.)
7 голосов
/ 16 марта 2009

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

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

Customer (id, ...)
Address (id, customer_id, address_type, valid_from, valid_to)

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

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

5 голосов
/ 22 декабря 2009

Мы движемся вперед с такой моделью:

Person (id, given_name, family_name, title, suffix, birth_date)
Address (id, culture_id, line1, line2, city, state, zipCode, province, postalCode)
AddressType (id, descriptiveName)
PersonAddress (person_id, address_id, addressType_id, activeDates)

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

Таблица адресов будет следовать схеме наследования таблиц на иерархии для дифференциации адресов на основе культуры; таким образом, адрес Соединенных Штатов будет содержать поле штата и почтовый индекс, а адреса Канады - провинцию и почтовый индекс.

Мы используем отдельную таблицу соединений, чтобы «дать» человеку адрес. Это освобождает наши другие организации - Персона и Адрес - от связей с другими организациями, если наш опыт показывает, что это усложняет ситуацию в будущем. Это также значительно упрощает подключение объектов Address ко многим другим типам объектов (люди, организации и т. Д.) И с различной контекстной информацией, связанной со ссылкой (например, activeDates в моем примере).

3 голосов
/ 16 марта 2009

При ответе на такие вопросы мне нравится использовать классификации DDD . Если это сущность, у нее должен быть отдельный идентификатор, если это объект значения, он не должен.

3 голосов
/ 15 марта 2009

Я бы предпочел # 1. Хорошая нормализация и четкое общение. Эта модель также позволяет использовать для обоих адресов один и тот же адресный объект (строка) , что я считаю весьма полезным. Слишком легко потеряться в дублировании этой информации.

3 голосов
/ 15 марта 2009

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

2 голосов
/ 16 марта 2009

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

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

Ранее в моей карьере я нормализовался, как сумасшедший, имея заказ, ссылающийся на клиента, который ссылается на адрес доставки. Это делало вещи «чистыми», но медленными и не элегантными в использовании. В настоящее время я использую объект заказа, который просто содержит всю информацию об адресе. Я на самом деле считаю это более естественным, поскольку клиент может изменить свой (по умолчанию?) Адрес, но адрес отправки, отправленной в 2007 году, всегда должен оставаться неизменным - даже если клиент переезжает в 2008 году.

В настоящее время мы внедряем VerySimpleAddressProtocol во входном проекте для стандартизации используемых полей.

2 голосов
/ 16 марта 2009

Опция 3 слишком ограничительна, и опцию 1 нельзя расширить, чтобы разрешить другие типы адресов без изменения схемы. Вариант 2, безусловно, является наиболее гибким и, следовательно, лучшим выбором.

1 голос
/ 16 марта 2009

Я бы выбрал вариант 1. Если вы хотите, вы можете даже немного изменить его, чтобы сохранить историю адресов:

Customer   (id, phys_address_id, mail_address_id)
Address    (id, customer_id, start_dt, end_dt, street, city, etc.)

Если адрес меняется, просто укажите дату окончания текущего адреса и добавьте новую запись в таблицу Address. phys_address_id и mail_address_id всегда указывают на текущий адрес.

Таким образом, вы можете хранить историю адресов, вы можете хранить несколько почтовых адресов в базе данных (по умолчанию mail_address_id), и если физический адрес и почтовый адрес идентичны, вы просто укажете phys_address_id и mail_address_id в одной записи.

1 голос
/ 15 марта 2009

Как и во многих случаях: Это зависит.

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

В тех случаях, когда вам нужно знать только один адрес клиента, почему вы смоделируете это для многих? Отношения один к одному удовлетворит ваши потребности здесь.

Внимание! Денормализация возможна только в случае проблем с производительностью.

...