可以支持专用属性的数据库模式

And*_*ers 8 database-design properties relational-database

我需要存储一组实体,其中有几个专用版本.它们具有一些共同属性,但专用属性包含特定于该实体的属性.

解决方案

数据存储是一个关系型DBMS,这不是讨论:-)具体来说,它是Microsoft SQL Server 2005.

我可以轻松地为公共属性创建一个表,然后为每个专用版本创建一个表.但是,以后可能需要将新实体添加到解决方案中,并且我不希望同时维护对象模型数据库模式.

另一个想法是创建一个表

reading(<common properties>, extended_properties)
Run Code Online (Sandbox Code Playgroud)

并且该extended_properties字段是扩展属性的某种序列化.我在想JSON或XML.我很可能会使用ORM框架,但我还没有决定.无论哪种方式,来自的专用实体的对象表示都reading可以公开{extended_property_name, value}包含来自该extended_properties字段的解析的键/值对的字典.

从这个http://msdn.microsoft.com/en-us/library/ms345117(SQL.90).aspx我收集XML字段,结合这些的模式,在DBMS中给出了类型化XML的概念.此外,涉及extended_properties字段中的XML内容的查询也可以考虑这些.

我想要的是

对我的解决方案建议的反馈,主要是具有reading扩展属性的表和序列化的建议.

此外,我意识到这是关系DBMS与基于键/值的商店相比的局限性之一.但是,肯定必须有一些建模技术来适应这种情况.

非常感谢任何反馈!

Per*_*DBA 13

安德斯,不要放弃任何完整性或硬度,例如类型安全.

(回应即将来临).

@Anders.不,完全没有,子类型很好(问题是你使用哪种形式,有什么不利/优势).不要放弃任何力量或诚信或类型安全或检查或DRI.您选择的表单将需要额外的支票和一些代码(取决于您的平台).

这个问题经常出现,但寻求者总是有一个狭隘的视角; 我一直在不变的集合中制作相同的语句(子集).我们的想法是评估所有选项.所以我正在写一篇文档.不幸的是,它需要更长时间 也许4页.还没准备好发帖.但是图表已经完成,我认为你已经完成了,你可以马上使用它.

警告:经验丰富的项目施工工程师
道路不适合大篷车或具有高Eek因子的读者

链接到四种替代数据模型◀在建文档中.为地板上的烂摊子道歉; 我很快就会收拾.

▶链接到IDEF1X表示法◀适用于不熟悉关系数据库建模标准的任何人.

  1. 它们都是关系型的,具有完整的完整性.

  2. 6NF选项.今天的Relational(SQL)不支持6NF; 它不会禁止它,它只是不提供5NF➔6NF结构.因此,您需要构建一个小目录,有些人称之为"元数据".实际上,它只是标准SQL目录(sys表)的扩展.所需的控制级别在每个选项中建模.

  3. 基本上EAV完全正确,具有完全控制和完整性(类型安全,声明参照完整性等),而不是通常的混乱.

您可能对这些相关的问题/答案感兴趣(特别是,请查看数据模型):

多重固定与抽象灵活

与数据库模式相关的问题

"简单"数据库设计问题

对评论的回应

...这样,我们可以轻松地获取与给定专用类型实例关联的"注释"行.这是这样做的方式,还是后来我会后悔这个决定?我们还缺少其他任何模式吗?

不明白你的意思.注释,注释,地址,最终被许多表中使用(驻留在列中),所以正确的方法是规范化它们; 提供一个评论表; 从任何需要它的表中引用.这是一个通用的Comment表.它用于产品(超类型),因为您说明了任何产品.它可以很容易地用在某些Product子类型中,而不是其他子类型中; 在这种情况下,FK将处于所述产品子类型中.

您的数据模型

Product 5NF /子类型示例中ProductType表的用途是什么?它是否包含与每个专用产品相对应的行,例如ProductCPU?我假设它表明基础产品是哪种专业化.

(图中的小错误,已更正.)

对,就是这样.

在标准关系术语中(不是作为数据库传递的不受控制的混乱),ProductType是鉴别器 ; 它标识哪个产品子类型适用于此产品.告诉您需要加入哪个产品子类型表.这对组合在一起构成了一个合乎逻辑 不要忘记生成视图,每个ProductType一个.

  • (对于四种数据模型中的每一种,请评估ProductType如何更改,确切地说它扮演的角色.)

  • "泛化专业化"是所有mumbo jumbo,OO术语; 没有越过界限,学习了Relational 30年来的能力.如果你对关系有一点了解,你将拥有全部的力量; 否则你只能使用非常有限的面向对象的方法(Ambler和Fowler有很多答案).请从12月11日开始阅读这篇文章.关系数据库模型实体,而不是对象; 不是课.

例如,在添加新产品时,您需要提供一个下拉选项,其中包含可以添加的产品类型.根据这个选择,可以推断出将数据放入哪些表中.正确吗?对于谈论应用程序代码我感到很遗憾,但我只需要对它进行透视

是.接下来要提供哪个页面(带有字段),供用户输入数据.

没问题,谈论将使用Rdb的应用程序代码,它们像丈夫和妻子(不是丈夫和奴隶)一样.

  • 对于您的OO类,在完成Rdb建模后,将类树映射到Rdb,与任何将使用它的应用程序无关.不是相反.并不依赖于一个应用程序.

  • 忘记"持久",它有许多问题(丢失更新;损坏数据完整性;有问题的调试;大规模争用;等等).对Rdb的所有更新都应该在交易中,符合ACID标准,可以使用30年,但Fowler和Ambler还没有读过它.通常这意味着一个存储的proc pre xact.

判别式是我们之前建立的Type-table的FK.它表示哪个规格.基类型遵循的子类型.但是判别表中包含的内容是什么?

从数据模型中不清楚吗?ProducType CHAR(1)(2). Name Char(30).

可以是一个显示友好的文本,说明UI用途的类型,

是的,除其他外,例如控制,约束等,在编码或报告时消除歧义.

但是它是否还包含包含特殊类型的确切表名?

不会.这对于数据来说有点过于实际.原则上不允许.

但这没有必要.

假设我对ID = 1的产品感兴趣.它具有判别性,表明它是ProductCPU.您将如何从应用程序代码中检索此ProductCPU?

如果你把所提供的模型,并实现它(所有表)为类,正确,等你申请将不会使用次数(这是列表,以及更通用的使用)的例子,将很容易.伪代码将是:

  • 鉴于ProductId(亚型未知的,因此您应该不会坐在AA亚型特异性窗口),加载Product只超
  • 基于Discriminator Product.ProductType,设置指标等,并加载适用的子类型,其中之一ProductCPU; ProductMemory; ProductDisk; ProductTape; 等等

  • 我所看到的(并且不同意),其加载给定的所有亚型OO方法ProductId一次:一个亚型是有效的; 其余的都是无效的.代码仍然必须将自身约束为Product基于的有效类Product.ProductType.

或者,例如.在上下文所在的位置,用户坐在特定于子类型的窗口中,例如.ProductCPU,设置该类,并请求ProductIdxxx.然后使用ProductCPUView.如果它返回零行,则它不存在.

  • 可能有ProductDiskxxx,但不是ProductCPUxxx.你如何处理,是否表明存在Product`xxx,但它不是一个CPU,还是不行,这取决于应用程序的要求.

对列表,其中,所述应用程序填充的栅格,而不考虑ProductId,使用次(各一个)加载每个网格.该SQL基于连接,不需要引用ProductType.