许多表到关系数据库中的单行

时间:2012-03-08 19:20:07

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

考虑我们有一个数据库,其中有一个表,这是一个销售记录。您销售产品和服务,因此您还有产品和服务表。

每次销售都可以是产品或服务,这使得设计数据库的选项如下所示:

  1. 为每种类型添加列,即。将Service_id和Product_id添加到Invoice_Row,其中两列都可以为空。如果它们都是空的,那么这是一项与任何事情无关的特别指控,但如果其中一个满意,那么它就是与该类型相关的一行。

  2. 添加一个奇怪的基于字符串/ id的系统,例如:Type_table,Type_id。这将分别是字符串/ varchar和整数,前者包含例如'Service',后者包含Service表中的id。这显然是松耦合和可怕的,但只要你只是从代码中访问数据库就可以解决它。

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

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

2 个答案:

答案 0 :(得分:2)

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

这种方法相对于其他方法的一个好处是,您最终不会得到一个具有许多可空列的表,这些列本质上成为描述任何内容的倾销场(“无架构”)。

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

答案 1 :(得分:1)

我认为这取决于用例。

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

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

  3. 我会亲自去接近方法2以避免加入并在出售时插入两个表格。