解决方案
数据存储是一个关系型DBMS,这不是讨论:-)具体来说,它是Microsoft sql Server 2005.
我可以轻松地为公共属性创建一个表,然后为每个专用版本创建一个表.但是,以后可能需要将新实体添加到解决方案中,并且我不希望同时维护对象模型和数据库模式.
另一个想法是创建一个表
reading(<common properties>,extended_properties)
并使extended_propertiesfield成为扩展属性的某种序列化.我在想JSON或XML.我很可能会使用ORM框架,但我还没有决定.无论哪种方式,来自读取的专用实体的对象表示可以公开包含来自extended_properties字段的解析的键/值对的字典{extended_property_name,value}.
从这个http://msdn.microsoft.com/en-us/library/ms345117(SQL.90).aspx我收集到XML字段,结合这些的模式,在DBMS中给出了类型化XML的概念.此外,涉及extended_propertiesfield中的XML内容的查询也可以考虑这些.
我想要的是
对我的解决方案建议的反馈,主要是带有阅读表和扩展属性序列化的建议.
此外,我意识到这是关系DBMS与基于键/值的商店相比的局限之一.但是,肯定必须有一些建模技术来适应这一点.
任何反馈都非常感谢!
解决方法
(回应即将来临).
@Anders.不,完全没有,子类型很好(问题是你使用哪种形式,有什么不利/优势).不要放弃任何力量或诚信或类型安全或检查或DRI.您选择的表单将需要额外的支票和一些代码(取决于您的平台).
这个问题经常出现,但寻求者总是有一个狭隘的视角;我一直在不变的集合中制作相同的语句(子集).我们的想法是评估所有选项.所以我正在写一篇文档.不幸的是,这需要更长时间也许4页.还没准备好发帖.但是图表已经完成,我认为你在球上,你可以马上使用它.
警告:仅有经验的项目施工工程师
道路不适合大篷车或具有高Eek因子的读者
链接到正在建设的文档中的▶Four Alternative Data Models◀.为地板上的烂摊子道歉;我很快就会收拾.
▶Link to IDEF1X Notation◀适用于不熟悉关系数据库建模标准的任何人.
>他们都是关系型的,具有完整的完整性.
> 6NF选项.今天的关系(sql)不支持6NF;它不允许它,它只是不提供5NF➔6NF结构.因此,您需要构建一个小目录,有些人称之为“元数据”.实际上,它只是标准sql目录(sys表)的扩展.所需的控制级别在每个选项中建模.
>基本上EAV正确完成,具有完全控制和完整性(类型安全,声明参照完整性等),而不是通常的混乱.
您可能对这些相关的问题/答案感兴趣(特别是,请查看数据模型):
Multiple Fixed vs Abstract Flexible
Database Schema-Related Problem
“Simple” Database Design Problem
对评论的回应
… That way,we can easily grab “Comment” rows associated with a given specialized type instance. Is this the way to do that,or will I regret that decision later? Is there any other pattern we’re missing?
不明白你的意思.注释,注释,地址,最终被许多表中使用(驻留在列中),所以正确的方法是规范化它们;提供一个评论表;从任何需要它的表中引用.这是一个通用的Comment表.它用于产品(超类型),因为您说明了任何产品.它可以很容易地用在某些产品子类型中,而不是其他子类型中;在这种情况下,FK将处于所述产品子类型中.
What is the purpose of the ProductType table in your Product 5NF/subtype example? Does it contain a row corresponding to each specialized Product,e.g.,Productcpu? I assume it indicates which specialization the base product is.
(图中的小错误,已更正.)
对,就是这样.
在标准关系术语中(不是作为数据库传递的不受控制的混乱),ProductType是鉴别器;它标识哪个产品子类型适用于此产品.告诉您需要加入哪个产品子类型表.这对组合在一起构成了一个合乎逻辑不要忘记为每个ProductType生成一个视图.
>(对于四种数据模型中的每一种,请评估ProductType如何更改,确切地说它扮演的角色.)
>“泛化专业化”是所有mumbo jumbo,OO术语;没有越过界限,学习了Relational 30年来的能力.如果你对关系有一点了解,你将拥有全部的力量;否则你只能使用非常有限的面向对象的方法(Ambler和Fowler有很多答案).请阅读12月10日起的this post.关系数据库模型实体,而不是对象;不是课.
For example,when adding a new product you’ll want to provide,say,a dropdown selection of which product types it is possible to add. Based on this selection,it can be deduced which tables to put the data in. Correct? I’m sorry for talking about application code,but I just need to put it into perspective
没问题,谈论将使用Rdb的应用程序代码,它们像丈夫和妻子(不是丈夫和奴隶)一样.
>对于您的OO类,在完成Rdb建模后,将类树映射到Rdb,与任何将使用它的应用程序无关.不是相反.并不依赖于一个应用程序.
>忘记“持久”,它有许多问题(丢失的更新;损坏的数据完整性;有问题的调试;大量争用;等等).对Rdb的所有更新都应该在交易中,符合ACID标准,可以使用30年,但Fowler和Ambler还没有读过它.通常这意味着一个存储的proc pre xact.
The discriminant is a FK to a Type-table as we established earlier. It denotes which
spec.sub type the base type adheres to. But what does the discriminant table contain in detail?
数据模型不清楚吗? ProducType CHAR(1)或(2).姓Char(30).
Could be a display-friendly text stating the type for UI-purposes,
是的,除了其他方面,例如控制,约束等,在编码或报告时消除歧义.
but does it also contain the exact table name which contains the specialized type?
不会.这对于数据来说有点过于实际.原则上不允许.
但这没有必要.
Say I’m interested in the Product with ID = 1. It has a discriminant indicating that it is a Productcpu. How would you go about retrieving this Productcpu from your app code?
如果您使用提供的模型并将其(所有表)实现为类,正确等等,这将很容易.您请求的示例将不使用视图(用于列表,更通用).伪代码将是:
>给定ProductId(子类型未知,因此您不应该坐在特定于子类型的窗口中),仅加载Product超类型
>基于Discriminator Product.ProductType,设置指标等,并加载适用的子类型,Productcpu之一; ProductMemory; ProductDisk; ProductTape;等等
>我已经看到(并且不同意)一次加载给定ProductId的所有子类型的OO方法:一个子类型有效;其余的都是无效的.代码仍然必须将自身约束为基于Product.ProductType的Product的有效类.
或者,例如.在上下文所在的位置,用户坐在特定于子类型的窗口中,例如. Productcpu,设置该类,并请求ProductId xxx.然后使用Productcpu View.如果它返回零行,则它不存在.
>可能有ProductDisk xxx,但不是Productcpu xxx.您是如何处理的,无论您是否指出产品`xxx但它不是cpu,都取决于应用程序的要求.
对于应用程序填充网格的列表,而不考虑ProductId,请使用视图(每个视图)加载每个网格.该sql基于连接,不需要引用ProductType.