Общая one-many таблица для нескольких объектов

Предположим, что у меня есть две таблицы, Клиент и Поставщик. Я хочу иметь общую таблицу адресов для адресов клиента и поставщика. У клиентов и Поставщиков может оба быть тот ко многим адресам.

Опция 1

Добавьте столбцы для AddressID к Customer и Vendor таблицы. Это просто не походит на чистое решение меня.

Customer     Vendor         Address
--------     ---------      ---------
CustomerID   VendorID       AddressID
AddressID1   AddressID1     Street
AddressID2   AddressID2     City...

Опция 2

Переместите внешний ключ в Address таблица. Для Клиента, Address.CustomerID будет заполнен. Для Поставщика, Address.VendorID будет заполнен. Мне не нравится это ни один - я не должен должен быть изменять таблицу адресов каждый раз, когда я хочу использовать ее для другого объекта.

Customer     Vendor         Address
--------     ---------      ---------
CustomerID   VendorID       AddressID
                            CustomerID
                            VendorID

Опция 3

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

Customer     Vendor         Address     
--------     ---------      ---------
CustomerID   VendorID       AddressID
                            FKTable
                            FKID

Так, я просто слишком придирчив, или являюсь там чем-то, о чем я не думал?

6
задан BenV 19 May 2010 в 04:46
поделиться

3 ответа

Я бы сказал, что недостающая часть головоломки - это отношение "is a", которое часто упускается из виду при моделировании данных; оно отличается от привычного отношения "has a". Отношения "есть" похожи на отношения наследования в объектно-ориентированном дизайне. Для моделирования этой связи вам понадобится базовая таблица, которая представляет общие атрибуты продавцов и клиентов. Например, мы можем назвать базовую таблицу "Организации":

Organizations       Vendors               Customers
--------------      ---------------------  ---------------------
OrganizationID(PK)  OrganizationID(FK/PK)  OrganizationID(FK/PK)
AddressID1(FK)
AddressID2(FK)

В этом примере поставщик "является" организацией, а клиент "является" организацией, в то время как организация "имеет" адрес. Таблицы Organizations, Vendors и Customers имеют общий ключ и общую последовательность ключей, обеспечиваемую ссылочной целостностью.

8
ответ дан 8 December 2019 в 15:59
поделиться

Я думаю, что из трех вариантов, которые вы указали, я был бы наиболее склонен выбрать вариант 1. Обычно у клиента или поставщика не более нескольких разных адресов, но если они делают, может быть, решение ниже подойдет вам лучше. Я бы не стал выбирать вариант 2, потому что, вероятно, нет смысла связывать адрес и с покупателем, и с продавцом одновременно. Я знаю, что вы, вероятно, зададите только один из этих идентификаторов за раз, но модель может сбивать с толку, и вам может потребоваться добавить специальную логику, чтобы убедиться, что для любой данной записи установлен только CustomerID или VendorID. Я бы определенно не стал использовать вариант 3, потому что вы не можете сделать FKID настоящим FK. Если вы хотите, чтобы столбец ссылался на несколько таблиц, вы не сможете использовать ограничение FK в базе данных для его принудительного применения.Кроме того, если вы планируете использовать ORM для взаимодействия с базой данных в коде, у них, как правило, возникают проблемы с «поддельными» внешними ключами, которые ссылаются на несколько таблиц в зависимости от отдельного столбца «дискриминатор».

Если вам нужно действительно открытое решение, вы можете создать отношения «многие ко многим» между клиентом и адресом, поставщиком и адресом.

Customer
--------
CustomerID (PK)

Vendor
------
VendorID (PK)

Address
-------
AddressID (PK)

CustomerAddress
---------------
CustomerID (FK/PK)
AddressID (FK/PK)

VendorAddress
-------------
VendorID (FK/PK)
AddressID (FK/PK)
6
ответ дан 8 December 2019 в 15:59
поделиться

вы можете изменить дизайн таблицы, чтобы она содержала следующие поля:

 Address_Type  (a flag to say that this is a customer, or a vendor)
 ID            (a common ID for both customer and vendor and depending on the flag you know what ID it is)
 Address       (Data of address itself)

или вы можете иметь две таблицы:

  • Таблица адресов, где нет ссылки на типы адресов. т.е. иметь оба
    • идентификатор объекта (ключ)
    • адрес
  • таблица типов адресов, где он будет указывать на запись и иметь флаг за пределами таблицы, чтобы иметь:
    • идентификатор объекта (FK для идентификатора объекта в приведенной выше таблице)
    • тип объекта (покупатель или поставщик)
0
ответ дан 8 December 2019 в 15:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: