sql – 在RDBMS中实现灵活的关系 – 真正的权衡是什么?

前端之家收集整理的这篇文章主要介绍了sql – 在RDBMS中实现灵活的关系 – 真正的权衡是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一堆产品,每种产品都有许多不同的可能属性.例如.产品A具有名称,大小,颜色,形状.产品B有名称,卡路里,糖等.解决这个问题的一种方法是:

1)创建表格

Products (id,name)
Attributes (id,name)
Product_Attributes (product_id,attribute_id,value as string)

这允许最大的灵活性,但我听到很多人建议不要这样,虽然我不知道为什么.我的意思是,如果这些表被称为团队,玩家,Team_Players,我们都同意这是适当的关系设计.

每个向我解释为什么这么糟糕的人都会在完全灵活的关系设计环境中这样做,你不会创建真正的表通过基本的几个基本初始表(例如object,attribute,object_attribute) – 我认为我们所有人都同意是坏事.但这是一个更加有限和包含的版本(只有产品,而不是系统中的每个对象),所以我认为将这两种架构组合在一起并不公平.

您遇到的哪些问题(经验或理论上的问题)使这个设计如此糟糕?

2)另一种解决方法是创建一个包含大量列,如大小,形状,重量,糖等的Product表,然后在末尾包含一些额外的列以提供一些灵活性.这将创建通常稀疏的行,主要填充NULL.人们倾向于喜欢这种方法,但我的问题是,在此方法失去性能优势之前,您可以拥有多少列?如果你有200列,我想这不再是一个聪明的举动,但100列呢? 50列? 25列?

3)我所知道的最后一种方法是将所有属性作为blob(可能是JSON)存储在Products表的单个列中.我喜欢这种方法,但感觉不对.查询很难.如果您希望以后能够轻松更改属性名称,则必须单独解析每个记录,或者通过某个ID将它们键入blob中.如果你去id路径然后你将需要另一个表属性,事情开始看起来像上面的方法#1,除了你将无法与你的blob加入attribute_id,所以我希望你不想查询任何东西按属性名称.

我喜欢这种方法的是你可以查询一个产品,在你的代码中你可以快速地访问它拥有的所有属性.如果删除产品,则无需清理其他表 – 易于保持一致.

4)我已经阅读了一些关于能够在一些RDBMS中索引强类型xml格式的东西,但老实说我对这种方法并不了解.

我被卡住了.我认为方法#1是最好的选择,但我读到的所有内容都说这样的方式很糟糕.考虑这个问题的正确方法是什么,以便能够确定给定情况下最佳方法是什么?显然,欢迎比我列出的更多想法!

解决方法

您可以通过对“实体属性值反模式”进行Google搜索来找到关于此主题的大量内容.

这种方法的一个问题是您最终将元数据与实际数据混合在一起.您的“属性”现在必须告诉数据库“值”列中的确切内容.这可能使得在前端,报告软件等中处理这些数据变得非常困难.

其次,您将很难在数据库中实际执行任何数据完整性.当你的产品具有“重量”属性时,阻止某人将“22英寸”放入值中的是什么?或者完全是非数字值.你可能会说,“好吧,我的应用程序将处理这个问题.”然后,每次要添加属性时都需要更改应用程序,因为应用程序需要知道如何处理它.如果您要完成所有这些工作,只需添加一个新列.

第三,如何强制给定产品具有所需的所有属性?在一行中,您可以使列NOT NULL,然后需要将该行放入数据库.您无法在EAV模型中强制执行此操作.

第四,这种模式通常会导致很多混乱.人们不确定支持哪些“属性”,或者他们复制属性,或者在创建报告时忘记处理属性.例如,如果我有“Weight(kg)”属性和“Weight(lbs)”的另一个属性,有人问我,“数据库中最重的产品是什么?”我最好记住,我需要检查两个属性.

第五,这种模式通常也会导致懒惰.嘿,没有理由对我们的系统可以处理的产品进行任何分析,因为无论出现什么,我们只会添加一些属性.根据我的经验,公司在创建良好的数据库设计所需的分析方面要好得多,而不是像这样的反模式.您将了解有关数据库,应用程序以及可能的业务的信息.

第六,为给定产品获取单行数据可能需要很多连接.您可以将属性作为单独的行返回,但现在您必须提供自定义列表框以列出这些产品等.同样,针对此模型编写搜索查询可能非常困难,并且在这两种情况下您都可能有性能问题.

这些只是我多年来遇到的一些问题.我确信还有其他人.

对您的系统而言,正确的解决方案取决于您的业务和应用程序的具体细节.如果您的产品属于共享公共属性的几个类别,则可以考虑使用子类型表而不是稀疏行.

猜你在找的MsSQL相关文章