Jar*_*red 7 database database-design entity-attribute-value
这是我多年来在多个地方看到的情景; 我想知道是否有其他人遇到过比我更好的解决方案......
我公司销售的产品数量相对较少,但我们销售的产品是高度专业化的(即为了选择给定的产品,必须提供大量的细节).问题在于,虽然选择给定产品所需的细节数量相对恒定,但所需的细节类型在不同产品之间差异很大.例如:
产品X可能具有识别特征,如(假设)
但是产品Y可能具有特征
在创建同时使用产品X和产品Y的订单系统时,问题(其中之一,无论如何)是订单行必须在某个时候引用它"销售"的内容.由于产品X和产品Y在两个不同的表中定义 - 并且使用宽表格方案的产品非规范化不是一种选择(产品定义非常深) - 很难看到在这样的定义订单行的明确方法订单输入,编辑和报告的实用方式.
我过去曾经尝试过的事情
如果其他人尝试了更多成功的不同策略,我肯定希望听到它.
谢谢.
如果您想保持数据完整性,并且您的产品类型相对较少且很少添加新产品类型,那么您描述的第一个解决方案是最好的.这是我在你的情况下选择的设计.仅当您的报告需要特定于产品的属性时,报告才会很复杂.如果您的报告只需要公共Products表中的属性,那就没问题了.
您描述的第二个解决方案称为"多态关联",它并不好.您的"外键"不是真正的外键,因此您不能使用DRI约束来确保数据完整性.OO多态性在关系模型中没有类比.
您描述的第三个解决方案,涉及将属性名称存储为字符串,是一种称为"实体 - 属性 - 值"的设计,您可以说这是一个痛苦且昂贵的解决方案.无法确保数据完整性,无法使一个属性为NOT NULL,无法确保给定产品具有某组属性.无法针对查找表限制一个属性.在SQL中无法进行许多类型的聚合查询,因此您必须编写大量应用程序代码来执行报告.只有在必须时才使用EAV设计,例如,如果您拥有无限数量的产品类型,则每行的属性列表可能不同,并且您的架构必须经常适应新的产品类型,而无需更改代码或架构.
另一种解决方案是"单表继承".这使用了一个非常宽的表,每个产品的每个属性都有一列.在与给定行上的产品无关的列中保留NULL.这实际上意味着您不能将属性声明为NOT NULL(除非它在所有产品的公共组中).此外,大多数RDBMS产品对单个表中的列数或行的总宽度(以字节为单位)有限制.因此,您可以通过这种方式表示的产品类型数量有限.
存在混合解决方案,例如,您可以在列中正常存储公共属性,但在Entity-Attribute-Value表中存储特定于产品的属性.或者,您可以在Products表的BLOB列中以其他结构化方式(如XML或YAML)存储特定于产品的属性.但是这些混合解决方案受到影响,因为现在必须以不同的方式获取某些属性
对于这种情况的最终解决方案是使用语义数据模型,使用RDF而不是关系数据库.这与EAV有一些共同点,但它更加雄心勃勃.所有元数据都以与数据相同的方式存储,因此每个对象都是自描述的,您可以像查询数据一样查询给定产品的属性列表.存在特殊产品,例如Jena或Sesame,实现此数据模型以及与SQL不同的特殊查询语言.
这可能会让你开始。需要一些改进
Table Product ( id PK, name, price, units_per_package)
Table Product_Attribs (id FK ref Product, AttribName, AttribValue)
Run Code Online (Sandbox Code Playgroud)
这将允许您将属性列表附加到产品。-- 这本质上是你的选项 3
如果你知道属性的最大数量,你可以去
Table Product (id PK, name, price, units_per_package, attrName_1, attrValue_1 ...)
Run Code Online (Sandbox Code Playgroud)
这当然会使数据库反规范化,但使查询更容易。
我更喜欢第一个选项,因为
| 归档时间: |
|
| 查看次数: |
3602 次 |
| 最近记录: |