2012-09-25 78 views
0

我想创建项目,其中每个项目可以有多个属性的数据库。我也有一个容器表(容器可以容纳物品)。每个容器都有多个必需的属性。项目属性必须符合容器属性的要求才能使项目适合容器。SQL - 动态属性

注:新的属性可以随时加入。

Example: 
Item 1 Attributes 
    Color: Red 
    Material: Aluminum 
    Length: 100 
    Width: 200 
    Rating: 4 

Container 1 Required Attributes: 
    Color=Red 
    Material=Aluminum 
    Length<105 
    Width<300 
    Rating=4 

我想找到所有适合容器的项目。如果Container Required Attributes表中有一个用于比较器的字段,则可以获取容器1的所有必需属性,然后根据比较器字段动态生成查询。我不是数据库专家,但这似乎不是一个好的设计。

另一种选择是为具有多个容器所要求的属性表 - 一个用于最大值,一个用于最低值,一个用于同值数字,一个同值串等

Example: 
Container 1 Maximum Attributes 
Length: 105 
Width: 300 

Container 1 Minimum Attributes 
<none> 

Container 1 Equal Attributes (Float) 
Rating: 4 

Container 1 Equal Attributes (String) 
Color: Red 
Material: Aluminum 

在这种情况下,我没有动态生成查询,但这似乎并不像最好的解决办法,因为我最终将需要为> =和< =表。

有没有人有一个更好的设计有什么建议?

+0

“'Steel'”是否小于''Wood'“,或者仅仅是数字属性的排序约束? –

+1

订购约束仅适用于数字属性。数字属性可以是<, >,<=, > =,==或!=。所有其他值可以是==或!=。 – mtb81

回答

0

查询参数只能是表达式而不是标识符(列)或运算符,因此避免动态生成查询的唯一方法是为所有容器设置一组固定的属性和比较结果,并仅存储值:

Container 1 Required Attributes: 
    Color: Red 
    Material: Aliminum 
    Max_Length: 105 
    Max_Width: 300 
    Rating: 4 

如果不同的容器有不同的数量或类型的需求,那么您的查询必须是动态的。 在这种情况下,拥有多个必需的属性表似乎对单个表没有任何好处。

如果属性存储在列中,则可以通过存储插入WHERE条件的单个字符串(如items.color='Red' AND items.Length<105 ...)使设计更具动态性。如果您希望稍后能够更改某些条件而不解析该字符串,则必须单独存储条件。

1

,当你这样说:

注:新的属性可以随时

携带一大堆后果的加入。 SQL最初的开发者并不打算支持我称之为“动态数据模型”的东西。在数据模型中发现一个新但缺失的属性只是由两个事件之一引起的:信息需求的变化或当前实现中发现的错误或遗漏。动态数据建模并不一定是坏事,但如果你抛出了很多自带的经典数据库管理学科的acheive它,你在同一时间抛出了相应的担保。

如果你走一步,并说,任何用户都可以添加一个新的属性,以及添加新的数据,还有更后果。两个用户可能会发现相同的属性,并给它不同的名称。这导致了“同义词问题”。两个用户可能会发现两个不同的属性,但会给这两个属性同名。这导致了“谐音问题”。如果你没有解决这些问题,从结果数据中理解几乎是不可能的。

我将提醒您两个与添加新属性到现有数据库有关的重要差异。在SQL层面上,这是DDL和DML的区别。在数据层面,这是元数据和数据之间的区别。你可能知道这一点,但是根据动态建模值得重新考虑。

在经典的数据库,要实现实体间现有的实体或关系的一个新发现的属性的方式,是由一个结构类似

alter table X add column Y .... 

这是DDL。执行DDL的权限通常仅限于DBA,并且不授予提供数据或使用应用程序作为接口来提供数据的用户。所以这个模型在这个意义上不是动态的。 DBA社区(如果有多个DBA)在更改模型之前互相授予。

当你做一些像添加一列到现有的表格时,会发生两件事。首先,修改实际表格的结构以适应新列。其次,数据字典被更新以反映表的变化。

数据diciotnary包含元数据,描述数据库本身模型的数据。用户表包含描述主题的数据。

通常,当您尝试在SQL中实现动态建模时,最终会在用户表中存储元数据(如列名称)的副本。您有责任维护此用户数据与实际数据结构之间的相关性,或者它们在数据字典中的反映。

你可以这样做。但是这是一大堆工作。而且你正在开始一段旅程,在这段旅程中,SQL可能不是获取目的地的最佳方式。