在我开发的应用程序中,不时出现需要SuperType / SubType模式的情况。当子类型的独占专业化适用时,我的问题通常会出现。专业化的独占性本身可以在编程语言层中轻松实施,因此利用该模式是一项微不足道的任务。但是,有时超类型不具有自身的标识属性(列) - 除了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...
存在引用documents
的关系表,并且每个文档的子类型可能有自己的整个子系统。因此SuperType / SubType模式。
如您所见,documents
表确实包含一个布尔列publicly_accessible
,它显然不是标识列。还有一些情况甚至没有这样的专栏。这意味着超级类型表只包含一个id
列,这对我来说不仅气味,而且在查看其内容时也会令人困惑。
我不能只删除documents
超类型,因为子类型表的数量可能会随着时间的推移而增长,并且有几个表明确引用documents
,这意味着表的数量引用documents
必须与子类型的数量相乘。
所以基本上我没有为我的超类型表识别列。任何想法如何重新设计/提出有用的识别专栏?
答案 0 :(得分:1)
您好我会添加另一个答案,因为这对评论很重要,我不想拿走第一个。
好吧,我认为你混淆了一些概念:
您的国家/地区,省份或car_wheels示例是“嵌套组件”。大多数情况下,它们与1:n相关(1个国家,许多省份,1个汽车,许多[井,可能4个]车轮)。有时会出现1:1的特殊情况(1辆汽车有1个发动机),但这不是定义,而是规则。你可以想到一辆带有两个引擎的汽车(例如otto和电池)。这不是继承(超类型[基类],类型和子类)。嵌套类型不适合“是”规则。一个省不是一个国家,一个轮子不是汽车......
继承始终是1:1。子类型(在您的情况下是特殊文档)是文档。
在这种情况下,您有树种数据:
通常,您会为每个专门的doc类型使用VIEWS来传递超类型和派生类型的复合数据,就好像它是一个表一样。使用SQL Server,您可以使用模式绑定定义此类VIEWS,并使用索引和约束。
从你的问题来看,我并不完全清楚,你不想改变基本概念。没问题,请坚持使用您的doc-table,但请考虑以下事项:您是否真的需要针对不同doc类型的专用表?你的唯一例子在所有情况下都说“name”,这是一个非常常见的信息,应该在超级表中。有什么好处?哪些信息对于PDF,DOC,HTML来说是如此独特,需要几个不同的表格?
在我们最大的项目中,我们只有一个文档表,适用于所有类型的文档,我真的认为没有优势可以在那里消失...有些列可以为空,在任何情况下都没有填充,那就是绝对足够......
祝你找到最合适的概念!
答案 1 :(得分:0)
我想到了一个DocumentType表。这个新表知道类型的名称和附加信息(一般存储位置,要查看的应用程序,......)
你可以让你的超级表离开并将这个新的id(带有FK)放入传播的doc-tables中,或者你保留你的超级表并把它放在那里......
可以公开访问的文档可能是doc-type级别的值或doc级别的值。在这种情况下,我更喜欢值级联:可能有一个布尔列,其中NOT NULL作为doc-type表的一部分,另一个可空列在doc级别(在超级表或扩展表中)。如果NOT NULL,则取此值,并回退到doc-type中的默认设置...
如果你使用诸如作者,创作时间,状态,最后编辑等常用信息,那么超级表只是有用的...