该数据库子类型关系应该如何建模?

时间:2012-09-11 22:01:25

标签: sql database-design web-applications language-agnostic

我正在修改传统的多租户应用程序,其中购物车功能将多个供应商和多个客户端存储在同一个数据库中。一个供应商的一些客户可能是不同供应商的客户。有些供应商可能实际上是另一家供应商的客户。

我目前有一个表格,主题为party_ID的超类型'派对',子表'公司'的表格,主键为company_ID(参考party_ID)和“供应商”角色的表格,主键为vendor_ID(引用company_ID)。我还有一个联结表,'client'的复合主键为vendor_IDparty_ID

我的问题是'order'表应该如何引用供应商和客户表?我首先想到的是,该表应该具有vendor_IDclient_IDorder_ID的复合主键(order_ID可以在整个表中自动递增,或者按{{{ 1}}) 但这似乎有点可疑,因为有三个属性组成了关键......

有没有人对这个话题有任何见解?大多数“购物车”只与单一供应商打交道,因此订单表只会将vendor_ID + client_ID列为外键。

谢谢!

3 个答案:

答案 0 :(得分:3)

  

我的问题是订单表应该如何引用供应商和   客户表?我的第一个想法是桌子应该有一个   'vendor_ID','client_ID'和'order_ID'的复合主键但是   这看起来有点可疑,因为有三把钥匙......

复合主键并不意味着三个键。它表示一个由三列组成的键。

但这不是真正的问题。

订单是会计记录; 一定不能随时间变化。除非你已经构建了时态表,否则存储ID号是有风险的,我怀疑你是否已经这样做了。如果供应商今天更改其名称,则其名称不再与先前订单上的名称匹配。 不得让会计记录发生这种情况。

除非您通过“订单”表示异常,否则我希望Order_id成为其主键。可能还有其他限制;甚至可能存在其他关键约束来防止仅由Order_id不同的重复订单。但我仍然希望Order_id成为订单表的主键。

如果供应商和客户是子类型,我希望您存储的任何(高风险)ID号引用子类型表中的ID号。在您的情况下,您似乎有一个额外的表来标识供应商的客户;它包含列{vendor_id,client_id}。 表的外键引用应该是显而易见的。

您的订单表应该有一个外键引用那个表,而不是供应商的一个外键和客户端的另一个外键。所以在订单表foreign key (vendor_id, client_id) references vendor_clients (vendor_id, client_id)中。供应商客户端表将需要主键约束或{vendor_id,client_id}上的唯一约束。

但除非你使用时态表,否则你不应该为会计做这件事。相反,您应该存储ID号和文本。

答案 1 :(得分:0)

对于您的主键,您只需要order_id

真的,我会使用的复合(和唯一)密钥是[vendor_idclient_idoccurredAt](其中occurredAt是时间戳) - 假设订单只能放置一毫秒。然而,这是一个广泛的关键,一些系统不欣赏这些。但是,您仍然需要这些列,并且可能已编入索引。

答案 2 :(得分:0)

我会从这样的事情开始。我承认我仍然不太明白你问题中company, vendor, and client之间的区别。正如Catcall所提到的,在此模型中,您不能删除PartiesPeopleOrganizations);应冻结会计记录 - 通常通过在订单表中捕获当前客户/供应商信息。


enter image description here