Sql 数据库设计中的继承

Sql 数据库设计中的继承,sql,oracle,database-design,inheritance,Sql,Oracle,Database Design,Inheritance,我正在设计一个新的实验室数据库,其中包含我的许多主要实体类型 每个实体的表将包含该实体所有类型(实体id、创建人、创建人等)的公共字段。然后,我将使用具体的继承(每个唯一属性集的单独表)来存储所有剩余字段 我相信这是针对每天通过实验室获取的标准类型数据的最佳设计。然而,我们通常有一个特殊的样本,通常伴随着发起者希望存储的特定值 问题:我应该如何为特殊(非标准)类型的实体建模 选项1:对特殊字段使用实体值 一个表(entity\u id,attribute\u name,numerical\u v

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

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

我相信这是针对每天通过实验室获取的标准类型数据的最佳设计。然而,我们通常有一个特殊的样本,通常伴随着发起者希望存储的特定值

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

选项1:对特殊字段使用实体值
一个表(
entity\u id
attribute\u name
numerical\u value
)将保存任何特殊实体的所有数据。
+更少的表格。
-无法强制要求特定属性。
-必须将(透视)行转换为低效的列。

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

选项3:在不同用户下使用特殊表进行具体继承。
将所有特殊表格放在不同的用户下。
+将所有特殊表格和标准表格分开。
+更容易在列表中搜索通用标准表,而无需搜索所有特殊表。

-只有几行的许多表的开销。

实际上,您描述的设计(公共表加上特定于子类型的表)被调用

将在子类型表中复制所有公共属性,并且不会像现在这样有超类型表

我强烈反对EAV。我认为这是一个SQL反模式。这似乎是一个优雅的解决方案,因为它需要更少的表,但你正在为自己设置一个很多头痛以后。您确定了几个缺点,但还有许多其他缺点。IMHO,只有在引入新的子类型时绝对不能创建新表,或者子类型的数量没有限制(例如,用户可以临时定义新属性)的情况下,才可以适当地使用EAV

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


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

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

首先,我并不认为选项3比选项2有什么好处。我认为,在另一个模式中分离特殊表将使您的应用程序更难维护,特别是如果以后发现“特殊值”之间存在共性的话

作为另一种选择,我要说: -将特殊值存储在XML片段(或blob)中。如今,大多数数据库都能够查询XML结构,因此不需要许多额外的表,您可以保持灵活性,以获得较小的性能影响

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

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

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

希望这有点帮助

-马丁


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

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

因此,它是灵活的,但它的性能优于eav模型


阅读:,和。

选项1模式也被称为“普遍关系”,乍一看,这似乎是一条不进行潜在困难数据建模的捷径。与使用多个表的更常见的数据模型相比,它无法轻松地进行简单的选择、更新和删除,而无需付出更大的努力。

实际上,我的设计是类和具体的混合。它对所有类型通用的字段使用类级别,对所有剩余字段使用具体级别(其中许多字段对几种类型通用)