0

我正在尝试创建一个项目数据库,其中每个项目都可以具有多个属性。我还有一个容器表(容器可以容纳物品)。每个容器都有多个必需的属性。项目属性必须满足容器属性的要求,才能使项目适合容器。

注意:可以随时添加新属性。

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

我想找到适合容器的所有物品。如果容器必需属性表有一个比较器字段,我可以获取容器 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

在这种情况下,我不必动态生成查询,但这似乎也不是最好的解决方案,因为我最终将需要用于 >= 和 <= 的表。

有人对更好的设计有什么建议吗?

4

2 回答 2

1

当你这样说时:

注意:可以随时添加新属性

这会带来很多后果。最初开发的 SQL 并不是为了支持我称之为“动态数据模型”的东西。在数据模型中发现新的但缺少的属性仅由以下两种事件之一引起:信息需求的变化或在当前实现中发现错误或遗漏。动态数据建模不一定是坏事,但如果你通过抛弃许多经典数据库管理附带的纪律来实现它,你同时也抛弃了相应的保证。

如果您更进一步,说任何用户都可以添加新属性以及添加新数据,那么后果会更加严重。两个用户可能会发现相同的属性,并给它不同的名称。这导致了“同义词问题”。两个用户可能会发现两个不同的属性,但给两者赋予相同的名称。这导致了“同音异义问题”。如果您不解决这些问题,那么从结果数据中获取意义几乎是不可能的。

我将提醒您在将新属性添加到现有数据库时很重要的两个区别。在 SQL 级别,这是 DDL 和 DML 之间的区别。在数据级别,这是元数据和数据之间的区别。您可能知道其中的大部分内容,但根据动态建模,值得重新考虑。

在经典数据库中,您实现现有实体或实体之间关系的新发现属性的方式是通过类似的构造

alter table X add column Y ....

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

当您执行向现有表添加列之类的操作时,会发生两件事。首先,实际表的结构被改变以适应新列。其次,更新数据字典以反映表的变化。

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

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

你可以这样做。但这是一大堆工作。而您正在踏上一段旅程,SQL 可能不是实现目标的最佳方式。

于 2012-09-26T12:58:57.847 回答
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 .... 这样做的缺点是,如果您希望以后能够在不解析该字符串的情况下更改某些条件,则必须单独存储条件。

于 2012-09-26T07:12:05.960 回答