在我迄今为止所做的每一个基于SQL的数据库应用程序中,迟早会出现以下三方面的要求:
存储数据,与上面的前两个项目符号大致匹配,非常简单:
null
,对于所有其他节点,此列将指向父节点的ID。虽然有许多资源建议使用不同的方法,尤其是在后一点(例如answers here,here或here),但我通常不会处于某个位置远离传统的静态关系数据库模式。因此,让我们简单地将上述假设为给定的。而且,我几乎不可能依赖于特定DBMS的细节;更常见的情况是系统应该与MS SQL Server,Oracle以及可能的其他系统一起作为后端,而不需要两个明显不同的产品版本。
然而,解决第三个项目总是有问题的(即使不考虑属性值的分层继承)。连接数取决于布尔表达式中考虑的不同属性数。或者,通过确定在自定义布尔表达式的任何情况下考虑的不同属性的最大数量,可以稍微减少连接数,这可以节省连接,但是使得生成的查询和用于生成它们的代码更不易理解和可维护。例如,
a = 5 or (b = 8 and c = 9)
可以使用2个连接到属性值表。
我一直能够“以某种方式”这样做,但由于这似乎是一种相当普遍的情况,我正在寻找在这种情况下生成SQL查询的“规范”方法。这里有“标准模式”吗?
答案 0 :(得分:1)
小心不要陷入内心平台效应。这是一个复杂的问题,SQL本身旨在处理复杂性。生成DDL以根据需要添加和删除列,并为查询生成简单的select语句。将每个元组类型(不同的属性集)存储为表格。
关于继承,我建议在应用程序或DAL中处理它,并且只存储非继承的值。在检索时,读取所有父行以计算功能值。如果确实需要从SQL访问“功能”值,请使用索引视图或触发器将它们与存储分开。
层次结构可以按照您的描述进行表示,但是简单的“父”列可能会使查询超出单个级别变得困难。查看SQL Server上的hierarchyid
或oracle上的CONNECT BY
。
避免使用EAV商店可以:
int
存储为int
,money
存储为money
)SELECT * FROM vwProducts WHERE Color = 'RED' ORDER BY Price ASC
)如果你想要一个EAV系统,因为你有太多的属性(每种类型大于1024)或者它们没有多少静态定义(每小时多次更改),我首先会避免使用关系数据库。请改用EAV(NoSQL)数据库服务器。
tl; dr:如果您有架构,请使用DDL告知服务器。如果不这样做,请使用更合适的服务器。