在我开发的应用程序中,有时会出现需要 SuperType/SubType 模式的情况。当应用子类型的专有特化时,通常会出现我的问题。特化的排他性本身可以很容易地在编程语言层中强制执行,因此使用该模式是一项微不足道的任务。但是,有时父类(super class)型本身没有标识属性(列)——除了 id,它存在于我创建的每个表中。实际标识在每个子类型表中指定。通过标识,我的意思是具有唯一值的列的组合,例如:
- 在
countries
表中有一个name
- 在
provinces
表中country_id
+name
- 在
car_wheels
表中有一个car_id
+wheel_position
我了解到几乎每个表都以某种方式包含标识列。
在我的特殊情况下,我有下表:
documents
-----------------------------
id | publicly_accessible
webpage_documents
----------------------------------------------------------
id | document_id | name (as well as certain other properties, too)
ajax_script_documents
-----------------------------
id | document_id | name
pdf_documents
-----------------------------
etc...
存在引用文档
的关系表,每个文档的子类型都可能有一个完整的子系统。因此出现了 SuperType/SubType 模式。
如您所见,documents
表确实包含一个 bool 列publicly_accessible
,这显然不是标识列。在某些情况下,甚至没有这样的专栏。这意味着父类(super class)型表只包含一个 id
列,这对我来说不仅有异味,而且在查看其内容时也会造成混淆。
我不能只删除 documents
父类(super class)型,因为子类型表的数量可能会随着时间的推移而增长,并且有几个表明确引用 documents
,这会这意味着引用 documents
的表的数量必须乘以子类型的数量。
所以基本上我没有为我的父类(super class)型表识别列。对如何重新设计/提出有用的识别列有什么想法吗?
最佳答案
您好,我会添加另一个答案,因为这对于评论来说太多了,我不想拿走第一个。
好吧,我认为你混淆了一些概念:
您的国家、省份或 car_wheels 示例是“嵌套组件”。大多数情况下,它们是 1:n 相关的(1 个国家、多个省份、1 辆汽车、许多 [好吧,可能是 4 个] 车轮)。有时会出现 1:1 的特殊情况(1 辆车有 1 个引擎),但这不是定义而是规则。您可以想到一辆有两个发动机的汽车(例如奥托发动机和电池发动机)。这不是继承(父类(super class)型 [基类]、类型和子类)。嵌套类型不符合"is"规则。一个省不是一个国家,一个轮子不是一辆汽车......
继承始终是 1:1。子类型(在您的情况下是特殊文档)是文档。
在这种情况下,您有树状数据:
- 公共(public)数据(在您的情况下,这将是 docID、名称、作者和状态信息以及 docType(作为边表的 FK 或独立的)
- 可覆盖数据:父类(super class)型或其一个边表定义了一个默认值,特殊文档行可能会否决该值(在您的情况下可能是关于权限、可访问性...)
- 专用数据:属于专用类型但不属于所有文档类型的数据
通常,您会为每个专门的文档类型使用 VIEWS 来传递父类(super class)型和派生类型的复合数据,使其表现得就像一个表。使用 SQL Server,您可以使用架构绑定(bind)、索引和约束来定义此类 View 。
从你的问题来看,我并不完全清楚你不想改 rebase 本概念。没问题,坚持使用您的文档表,但请考虑以下事项:您真的需要针对不同文档类型的专用表吗?您唯一的示例在所有情况下都说明“名称”,这是一个非常常见的信息,应该放在 super 表中。有什么好处?什么信息对于 PDF、DOC、HTML 如此独特,以至于需要几个不同的表格?
在我们最大的项目中,我们只有一个文档表用于所有类型的文档,我真的认为离开那里没有任何好处......有些列可以为空并且在任何情况下都不会被填充,就是这样绝对够了……
祝您找到最佳和合适的概念!
关于mysql - 没有(标识)唯一属性的父类(super class)型表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33145811/