- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个关于关系数据库中父类(super class)型-子类型设计的问题。如果我有一个带有两个子类型表的父类(super class)型,我会将与两个子类型表的 PK 相关的父类(super class)型的 PK 作为 FK。假设我有这样的事情:
类型ID公钥
ID主键类型ID FK
ID PK,FK
ID PK,FK
在数据库方面,我如何确保给定类型的父类(super class)型 ID 仅放入适当的子类型表中?例如,我不希望将类型 A 的父类(super class)型 ID 放入子类型 B 表中。有没有办法很容易地防止这种情况发生在数据库端?我知道这可以用代码处理,但如果代码有错误怎么办?或者,如果有人将错误的 ID 手动输入到其中一个子类型表中怎么办?我想我正在寻找某种方法来使这在数据库端成为不可能。
有什么想法吗?也许 Supertype 表上的 PK 应该是 ID 和 TypeID 组合,在 ID 列上具有唯一约束,以防止两种类型都出现在 SuperType 表中的记录......然后 Subtype 表将具有组合 ID 和 TypeID PK对 TypeID 的约束只能是适合子类型表的类型??
最佳答案
On the database side, how would I ensure that Supertype ID's of a given type were only put into the appropriate subtype table?
在支持延迟约束的 DBMS 上,您可以这样做:
在 SuperType
上有以下约束:
CHECK (
(
(SubtypeAId IS NOT NULL AND SubtypeAId = SuperTypeId)
AND SubtypeBId IS NULL
)
OR
(
SubtypeAId IS NULL
AND (SubtypeBId IS NOT NULL AND SubtypeBId = SuperTypeId)
)
)
这些奇特的循环 FKs1 与 CHECK 相结合确保子级的排他性和存在(CHECK 确保恰好是以下之一:SuprerType.SubtypeAId
,SuprerType.SubtypeBId
是非 NULL 且匹配 SuperTypeId
)。延迟子 FK(或 CHECK,如果您的 DBMS 支持的话)以在插入新数据时打破先有鸡还是先有蛋的问题。
1 SubtypeA.SubtypeAId
引用 SuperType.SuperTypeId
和 SuperType.SubtypeAId
引用 SubtypeA.SubtypeAId
,其他子类型同上。
如果您的 DBMS 不支持延迟约束,您可以允许(在 CHECK 中)两个字段都为 NULL 并放弃强制执行 child 的存在(您仍然保持排他性)。
或者,也可以像这样强制执行排他性(但不存在):
注意:如果 DBMS 不支持“键外”FK,您可能需要在 SuperType {SuperTypeId, TypeId}
上添加冗余 UNIQUE。
在 SubtypeA
上有以下约束:
CHECK(TypeId = 1)
SubtypeB
的以下约束:
CHECK(TypeId = 2)
我使用 1 和 2 来表示特定的子类型 - 你可以使用任何你喜欢的东西,只要你是一致的。
此外,您可以考虑通过为子类型的 TypeId
(例如 Oracle 11 virtual columns)使用计算列来节省存储空间。
顺便说一句,通过应用程序逻辑强制存在和排他性并不被认为是一个糟糕的整体策略。大多数时候,您应该努力在数据库中尽可能多地执行完整性,但在这种特殊情况下,在应用程序级别执行此操作通常被认为是合理的,可以避免上述复杂情况。
最后,“所有类在单独的表中”并不是实现继承的唯一策略。如果您使用“一个表中的所有内容”或“单独表中的具体类”来实现继承,则强制子类型的存在和排他性变得更加容易。
看看this post了解更多信息。
关于database - 超型-亚型数据库设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12255731/
我想了解 Isabelle/HOL 亚型。我在对最后一个 SO 问题的部分回答中解释了为什么它对我很重要: Trying to Treat Type Classes and Sub-types Lik
我是一名优秀的程序员,十分优秀!