Ben*_*enV 6 database database-design data-modeling
假设我有两个表,即客户和供应商.我想为客户和供应商地址提供一个公共地址表.客户和供应商都可以拥有一个到多个地址.
将AddressID的列添加到Customer和Vendor表中.这对我来说似乎不是一个干净的解决方案.
Customer Vendor Address
-------- --------- ---------
CustomerID VendorID AddressID
AddressID1 AddressID1 Street
AddressID2 AddressID2 City...
Run Code Online (Sandbox Code Playgroud)
将外键移动到Address表中.对于客户,Address.CustomerID将填充.对于供应商,Address.VendorID将填充.我也不喜欢这个 - 每次我想将它用于另一个实体时,我都不需要修改地址表.
Customer Vendor Address
-------- --------- ---------
CustomerID VendorID AddressID
CustomerID
VendorID
Run Code Online (Sandbox Code Playgroud)
我也看到了这一点 - 在Address表上只有一个外键列,另一列用于标识该地址所属的外键表.我不喜欢这个,因为它要求所有外键表具有相同类型的ID.一旦你开始对它进行编码,它似乎也很混乱.
Customer Vendor Address
-------- --------- ---------
CustomerID VendorID AddressID
FKTable
FKID
Run Code Online (Sandbox Code Playgroud)
那么,我是不是太挑剔了,还是有什么我没有想到的?
我要说的是,这个难题的缺失部分是数据建模中经常被忽视的"是一种"关系; 这与熟悉的"有"关系截然不同."是一种"关系类似于面向对象设计中的继承关系.要对此进行建模,您需要一个表格,代表供应商和客户的共同属性.例如,我们可以调用基表"组织":
Organizations Vendors Customers
-------------- --------------------- ---------------------
OrganizationID(PK) OrganizationID(FK/PK) OrganizationID(FK/PK)
AddressID1(FK)
AddressID2(FK)
Run Code Online (Sandbox Code Playgroud)
在此示例中,供应商"是"组织,而客户"是"组织,而组织"具有"地址."组织","供应商"和"客户"表共享公用密钥和由参照完整性强制执行的公用密钥序列.
我认为在你给出的三个选项中,我最倾向于使用选项1.通常,客户或供应商不会有多个不同的地址,但如果他们这样做,可能下面的解决方案会更好为了你.我不会选择选项2,因为将地址与客户和供应商同时关联可能没有意义.我知道您可能一次只设置其中一个ID,但模型可能会令人困惑,您可能需要添加特殊逻辑以确保在任何给定记录上只设置CustomerID或VendorID.我绝对不会做选项3,因为你不能让FKID成为真正的FK.如果希望列引用多个表,则无法在数据库中使用FK约束来强制执行该表.加,
如果您想要一个真正开放式的解决方案,您可以在客户和地址以及供应商和地址之间创建多对多关系.
Customer
--------
CustomerID (PK)
Vendor
------
VendorID (PK)
Address
-------
AddressID (PK)
CustomerAddress
---------------
CustomerID (FK/PK)
AddressID (FK/PK)
VendorAddress
-------------
VendorID (FK/PK)
AddressID (FK/PK)
Run Code Online (Sandbox Code Playgroud)