database-design - 可以支持专用属性的数据库架构

标签 database-design properties relational-database

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

解决方案

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

我可以轻松地为公用属性创建一个表,然后为每个专用版本创建一个表。但是,很可能以后必须将新实体添加到解决方案中,并且我不想同时维护对象模型和数据库架构。

另一个想法是创建一个表

reading(<common properties>, extended_properties)


并且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的局限性之一。但是,肯定必须有一些建模技术来适应这种情况。

任何反馈,不胜感激!

最佳答案

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

对评论的回应


...这样,我们可以轻松获取与给定的特殊类型实例关联的“注释”行。是这样做的方法,还是我以后会后悔这一决定?我们还有其他模式吗?


不明白你的意思。注释,注释,地址最终在许多表中使用(驻留在各列中),因此正确的方法是将其标准化。提供一张表格供评论;从任何需要它的表中引用。这是通用的注释表。因为您声明了任何产品,所以用在产品(超类型)中。它可以在某些产品子类型中轻松使用,而在其他产品子类型中则不容易使用。在这种情况下,FK将在所述产品子类型中。

Your Data Model


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


(图中的小严重错误,已更正。)

对,就是这样。

用标准关系术语(不是作为数据库传递的不受控制的消息),ProductType是鉴别符;它标识哪些产品子类型适用于此产品。告诉您需要与哪个产品子类型表连接。这对在一起构成了一个合乎逻辑的产品。不要忘记生成视图,每个产品类型一个。


(请针对四个数据模型分别评估ProductType的变化方式,以及它所扮演的角色。)
“通用化—专业化”是面向对象的所有术语。无需跨越界限并了解Relational 30年来的能力。如果您了解一些有关Relational的知识,那么您将拥有全部能力;否则,您仅限于非常有限的面向对象的方法(Ambler和Fowler有很多要回答的问题)。请从10年12月11日开始阅读this post。关系数据库不是实体而是实体,而是实体。不是课程。



例如,添加新产品时,您需要提供例如可以添加哪些产品类型的下拉选择。基于此选择,可以推断出将数据放入哪些表。对吗?很抱歉谈论应用程序代码,但我只需要将其放在透视图中


是。接下来要提供什么页面(带有字段),供用户输入数据。

毫无疑问,讨论将使用Rdb的应用程序代码,它们像夫妻一样(而不是夫妻)在一起。


对于OO类,在完成Rdb建模后,将Class树映射到Rdb,而与将使用它的任何应用程序无关。并非相反。而不依赖于一个应用程序。
忘了“持久”,它有很多问题(丢失更新;损坏的数据完整性;有问题的调试;大量争用;等等)。 Rdb的所有更新都应在符合ACID要求的“交易”中进行30年,但Fowler和Ambler尚未阅读。通常这意味着一个存储的过程。



判别式是我们前面建立的类型表的FK。它表示哪个规格。基本类型遵守的子类型。但是判别表详细包含什么?


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


可能是易于显示的文本,说明用于UI的类型,


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


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


否。这太实际了,无法放入数据中。原则上不允许。

但这不是必需的。


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


如果采用提供的模型并将其(所有表)正确地实现为类,则将很容易。您请求的示例将不使用视图(用于列表,更通用)。伪代码为:


给定ProductId(子类型未知,因此您不应该坐在特定于子类型的窗口中),仅加载Product超类型
根据鉴别符Product.ProductType,设置指示器等,并加载ProductCPU; ProductMemory; ProductDisk; ProductTape之一的适用子类型;等等
我已经看到(并且不同意)OO方法立即为给定的ProductId加载所有子类型:一种子类型有效;另一种有效。其余的无效。代码仍然必须将自身限制为基于ProductProduct.ProductType有效类。


或者,例如。在上下文所在的位置,用户正坐在特定于子类型的窗口中。设置了该类的ProductCPU,并请求ProductId xxx。然后使用ProductCPU视图。如果返回零行,则不存在。


可能有一个ProductDisk xxx,但没有一个ProductCPU xxx。如何处理,是否指示存在Product`xxx但不是CPU,则取决于应用程序要求。


对于列表,其中应用程序填充了网格,而不考虑ProductId,请使用视图(每个视图)加载每个网格。该SQL是基于联接的,不需要引用ProductType

关于database-design - 可以支持专用属性的数据库架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4304217/

相关文章:

java - 使用@Value 注解时,Spring 究竟是如何注入(inject)属性的?

c# - 按名称过滤对象属性

python - 有没有办法确保对变量执行验证而不是@property?

mysql - 如何为数据库生成 ERD 或 UML?

MySQL表设计: Primary Foreign Multi-Column Key possible?

mysql - 2个多对多关系的数据库建模

database - 使用用户定义的类型作为主键

c# - 如何正确呈现复选框列表并将其写入数据库? (理论/逻辑帮助)

relational-database - PetaPoco 和多对一、一对多和多对多关系

单机中的 NoSQL