没有(标识)唯一属性的超类型表

时间:2015-10-15 10:15:01

标签: mysql sql database subtype

在我开发的应用程序中,不时出现需要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必须与子类型的数量相乘。

所以基本上我没有为我的超类型表识别列。任何想法如何重新设计/提出有用的识别专栏?

2 个答案:

答案 0 :(得分:1)

您好我会添加另一个答案,因为这对评论很重要,我不想拿走第一个。

好吧,我认为你混淆了一些概念:

您的国家/地区,省份或car_wheels示例是“嵌套组件”。大多数情况下,它们与1:n相关(1个国家,许多省份,1个汽车,许多[井,可能4个]车轮)。有时会出现1:1的特殊情况(1辆汽车有1个发动机),但这不是定义,而是规则。你可以想到一辆带有两个引擎的汽车(例如otto和电池)。这不是继承(超类型[基类],类型和子类)。嵌套类型不适合“是”规则。一个省不是一个国家,一个轮子不是汽车......

继承始终是1:1。子类型(在您的情况下是特殊文档)文档。

在这种情况下,您有树种数据:

  1. 公共数据(在您的情况下,这将是docID,名称,作者和状态信息以及docType(作为边桌或独立的FK)
  2. 可覆盖的数据:超类型或其一个侧表定义了一个默认值,特殊的doc行可能会覆盖此值(在您的情况下可能是关于权限,可访问性的内容......)
  3. 专业数据:属于专业类型但不属于所有文档类型的数据
  4. 通常,您会为每个专门的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中的默认设置...

如果你使用诸如作者,创作时间,状态,最后编辑等常用信息,那么超级表只是有用的...