数据库设计中的继承

时间:2009-08-14 19:35:36

标签: sql oracle database-design inheritance

我正在设计一个新的实验室数据库,其中包含许多类型的主要实体。

每个实体的表将包含该实体的所有类型(entity_id,created_on,created_by等)共有的字段。然后,我将使用具体的继承(每个唯一属性集的单独表)来存储所有剩余的字段。

我相信这是每天通过实验室传输的标准数据类型的最佳设计。但是,我们经常会有一些特殊的样本,这些样本通常伴随着发起者想要存储的特定值。

问题:我应该如何为特殊(非标准)类型的实体建模?

选项1:对特殊字段使用entity-value 一个表格(entity_idattribute_namenumerical_value)将包含任何特殊实体的所有数据。
+更少的桌子。
- 不能强制要求特定属性 - 必须将行(数据透视)转换为效率低的列。

选项2:严格的具体继承 为每个单独的特殊情况创建单独的表格 +遵循所有其他规则
- 只有几行的许多表的开销。

选项3:具有不同用户下的特殊表格的具体继承 将所有特殊表放在不同的用户下 +保持所有特殊和标准表分开 +更容易在列表中搜索通用标准表而无需搜索所有特殊表格 - 只有几行的许多表的开销。

5 个答案:

答案 0 :(得分:9)

实际上,您描述的设计(公用表格加特定于子类型的表格)称为Class Table Inheritance

Concrete Table Inheritance会在子类型表中重复所有公共属性,并且您没有像现在这样的超类型表。

我强烈反对EAV。我认为它是一个SQL反模式。它可能看起来像一个优雅的解决方案,因为它需要更少的表,但你后来为自己设置了很多头痛。你发现了一些缺点,但还有很多其他缺点。恕我直言,只有在你引入新的子类型时,绝不能创建新表,或者你有无限数量的子类型(例如,用户可以定义新的属性)时,才能正确使用EAV。

你有很多子类型,但仍然是有限数量的子类型,所以如果我在做这个项目,我会坚持类表继承。每个子类型可能只有几行,但至少可以保证每个子类型中的所有行都有相同的列,如果需要可以使用NOT NULL,可以使用SQL数据类型,可以使用参考完整性约束等。从关系角度来看,它是比EAV更好的设计。

您未提及的另一个选项称为Serialized LOB。也就是说,为自定义属性的半结构化集合添加BLOB列。在该列中存储XML,YAML,JSON或您自己的DSL。您将无法使用SQL轻松解析BLOB中的各个属性,您必须将整个BLOB提取回应用程序并在代码中提取单个属性。所以在某些方面它不太方便。但如果这样可以满足您对数据的使用,那么就没有错。

答案 1 :(得分:1)

我认为这主要取决于您希望如何使用这些数据。

首先,我并没有真正看到选项3相对于选项2的好处。我认为将另一个模式中的特殊表分开将使您的应用程序更难维护,特别是如果稍后在'特殊值之间找到共性时”。

作为另一种选择,我会说: - 将特殊值存储在XML片段(或blob)中。目前,大多数数据库都能够查询XML结构,因此无需额外的表,您可以保持灵活性,从而实现轻微的性能损失。

如果将所有特殊值放在一个表中,则会得到一个非常稀疏的表。大多数普通的DBMS都无法很好地处理这个问题,但是有些实现专门用于此。你可以从中受益。

您是否经常需要查询键值对?如果您基本上通过它的entry_id访问该表,我认为拥有一个键值表并不是一个糟糕的设计。当您需要查询特殊值时,kay列上的额外索引甚至可能会帮助您。如果在数据库之上构建应用程序层,则键值表将映射到Map或Hash结构上,也可以轻松使用。

它还取决于您要存储的不同类型的值。如果有许多不同类型,需要轻松访问(而不是序列化/反序列化为XML /字符串),您可能希望将类型存储在单独的列中,但这通常会导致非常复杂的设计。

希望这有帮助(一点点)。

-Maarten

答案 2 :(得分:1)

http://en.wikipedia.org/wiki/Entity-Attribute-Value_model

建议您在决定使用实体值表之前阅读有关实体值表的问题。

答案 3 :(得分:1)

Oracle可以很好地处理稀疏填充表。我认为您可以使用公司salesforce使用的类似方法。他们使用包含大量列的表,并在需要时创建列。您可以比eav模型更好地索引这些列。

因此它很灵活,但它比eav模型表现更好。

阅读:Ask Tom 1Ask Tom 2High ScalabiltySalesForce

答案 4 :(得分:1)

“选项1”模式也称为“通用关系”首先看起来似乎是一个不做潜在困难数据建模的捷径。它交换了毫不费力的数据建模,因为它无法进行简单的选择,更新,删除,而不需要比使用多个表的更常见的数据模型更多的努力。