【问题标题】:Many tables to a single row in relational database关系数据库中的许多表到单行
【发布时间】:2012-03-08 19:20:06
【问题描述】:

假设我们有一个数据库,其中有一个表,该表是销售记录。您同时销售产品和服务,因此您也有一个产品和服务表。

每次销售都可以是产品或服务,因此设计数据库的选项如下:

  1. 为每种类型添加列,即。将 Service_id 和 Product_id 添加到 Invoice_Row,这两个列都可以为空。如果它们都为空,则这是与任何事物无关的临时收费,但如果满足其中之一,则它是与该类型相关的一行。

  2. 添加一个奇怪的基于字符串/id 的系统,例如:Type_table、Type_id。这将分别是字符串/varchar 和整数,前者将包含例如“服务”,而后者将包含服务表中的 id。这显然是松散耦合和可怕的,但只要您只从代码中访问数据库,这是一种解决方法。

  3. 使用新表抽象出“可收费的东西”的概念,其中 Product 和 Service 现在是其中的抽象,并且在 Invoice_Row 表上,您可以链接到 ChargeableEntity_id 之类的东西。然而,这里的 ChargeableEntity 表本质上是多余的,因为它也需要某种方式来链接到抽象的“后端”表,这让我们一直回到同样的问题。

您会选择哪种方式,或者解决此问题的其他替代方法是什么?

【问题讨论】:

  • 如果您想根据销售类型(产品或服务)存储不同的销售详细信息,这可能会变得复杂。
  • @ypercube 是的,这基本上是我的选项#1,但我不确定这是否是正确的方法。就像你说的那样它可能会变得复杂,如果添加不同的类型(除了产品/服务,是的,我知道它很少见)怎么办?
  • 嗯,不,我的意思是链接另一个问题。在此处查看 gbn 的答案(选项 3):NULLs in a composite primary key - SQL Server。那些宠物/猫/狗是您的 ChargableEntity/产品/服务
  • 如果添加了不同的类型,则添加另一个(子类型)表。

标签: sql-server database database-design relational-database


【解决方案1】:

您实质上要问的是如何在关系数据库中实现多态性。这个问题有很多方法(正如你自己演示的那样)。一种解决方案是使用“每个类的表”继承。在此设置中,将有一个父表(类似于您的“收费项目”),其中包含一个唯一标识符以及产品和服务共有的字段。将有两个子表,产品和商品:每个都包含该实体的唯一标识符和特定于它的字段。

与其他方法相比,这种方法的一个好处是您最终不会得到一个包含许多可空列的表,而这实际上会成为描述任何内容的垃圾场(“无模式”)。

一个缺点是随着继承层次结构的增长,获取实体的所有数据所需的连接数也会增加。

【讨论】:

  • 是的,我相信这是我想要采用的方法(#3),但问题仍然是应该如何处理将收费项目链接回它的“基本类型”?当然,如果你明白我的意思的话,这会让我们回到同一个问题,唯一的解决方案是 #1 或 #2,以补充 #3..
  • 您能解释一下“基本类型”是什么意思吗?您指的是哪种基本类型?按照我的理解,“收费项目”是基本类型。
  • 是的,是的,这就是我的意思,其中 Chargeable Item 是基本类型,而 Product/Service 则来自它。也许我正在以错误的方式思考它。也许销售应该链接到收费项目,但是然后产品将链接到收费项目(一个->一个),而不是想办法继续将收费项目链接到产品/服务。
  • @rudi:没错。使用选项 3,FK 应该来自 Product->ChargableItem 和 Service->ChargableItem。
  • 然后,对于其他关系,从 Sale->ChargableItem。
【解决方案2】:

我相信这取决于用例。

  1. 您可以将公共列放在一个表中,并将产品和服务特定列放在其自己的表中。这里的交易是您需要加入一些东西。

  2. 否则,如果您维护两个单独的表,一个用于产品,另一个用于销售。您使用应用程序逻辑来确定要插入哪个表。获得所有销售基本上意味着获得所有产品和获得所有销售的结合。

我会亲自采用方法 2,以避免在进行销售时连接并插入两个表。

【讨论】:

  • 好吧,无论如何我都会选择你的#1,我的主要问题是如何将这些不同类型的表格链接到“公共”行。
猜你喜欢
  • 2013-01-29
  • 2010-12-07
  • 2011-11-04
  • 1970-01-01
  • 2010-09-16
  • 2020-03-26
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
相关资源
最近更新 更多