如何最好地表示数据库中具有变量属性的项目?

时间:2009-02-05 01:03:50

标签: database database-design

假设您要创建小部件列表

Widget制造商都创建具有不同数量和类型的属性的小部件。 Widget卖家对于他们想要存储在数据库和显示中的属性类型和数量都有不同的偏好。

现在的问题是,每次添加新窗口小部件时,它上面可能有任何其他窗口小部件当前不存在的属性,目前您可以通过修改表并为其添加新列来实现此目的。属性,然后修改所有表单和报告以反映此更改。

如何创建一个数据库,其中考虑到窗口小部件上的属性是流动的,并且可以从窗口小部件更改为窗口小部件。

理想情况下,小部件属性应该是用户可以根据他/她的偏好和需求定义的内容

2 个答案:

答案 0 :(得分:3)

我会有一个用于小部件的表和一个用于小部件属性的表。例如:

Widgets
   - Id
   - Name

WidgetAttributes
   - Id
   - Name

然后,您将拥有另一个表,其中包含哪些小部件具有哪些属性:

WidgetAttributeMap
  - Id
  - WidgetId
      (a value from the Id column in the Widget table)
  - WidgetAttributeId
      (a value from the Id column in the WidgetAttribute table)

这样,您可以通过修改WidgetAttributeMap表中的行来向窗口小部件添加属性,而不是通过修改窗口小部件表的结构。

答案 1 :(得分:2)

casperOne正在显示方式,虽然我个人会为属性值添加一个表,最后以

结尾
Widgets
  -WidgetID (pk)
  -Name

WidgetAttributes
  -AttributeID (pk)
  -Name

WidgetHasAttribute
  -WidgetID (pk)
  -AttributeID (pk)

WidgetAttributeValues
  -ValueID (pk)
  -WidgetID
  -AttributeID
  -Value

为了检索结果,您希望连接表并执行聚合连接,这样您最终可以得到类似的数据(例如):

Name      Properties
Widget1   Attr1:Value1;Attr2:Value2;...etc

然后,您可以拆分业务逻辑层中的属性字符串,并根据需要使用。

关于如何加入数据的建议:

SELECT w.Name, wa.Name + ':' + wav.Value 
FROM ((
    Widgets w 
  INNER JOIN 
    WidgetHasAttribute wha 
   ON w.WidgetID = wha.WidgetID)
  INNER JOIN WidgetAttributes wa
   ON wha.AttributeID = wa.AttributeID)
  INNER JOIN WidgetAttributeValues wav
   ON (w.WidgetID = wav.WidgetID AND wa.AttributeID = wav.AttributeID)

您可以阅读有关聚合连接here的更多信息。

就性能而言,只要您确保索引所有经常读取的列 - 这就是

,这应该不是问题。
  • 所有ID列将在join子句中进行比较
  • WidgetAttributes.Name和WidgetAttributeValues.Value,因为它们将被连接