Database 如何在数据库中用属性变量#最好地表示项目?
假设您想要创建一个小部件列表 小部件制造商都创建具有不同数量和类型属性的小部件。小部件销售商对于他们想要在数据库中存储和显示的属性的类型和数量都有不同的偏好 现在的问题是,每次您添加一个新的小部件时,其上可能有其他任何小部件当前不存在的属性,而当前您可以通过修改表并为该属性添加一个新列,然后修改所有表单和报表以反映此更改来完成此操作 您如何着手创建一个数据库,该数据库考虑到小部件上的属性是流动的,并且可以随小部件的不同而变化Database 如何在数据库中用属性变量#最好地表示项目?,database,database-design,Database,Database Design,假设您想要创建一个小部件列表 小部件制造商都创建具有不同数量和类型属性的小部件。小部件销售商对于他们想要在数据库中存储和显示的属性的类型和数量都有不同的偏好 现在的问题是,每次您添加一个新的小部件时,其上可能有其他任何小部件当前不存在的属性,而当前您可以通过修改表并为该属性添加一个新列,然后修改所有表单和报表以反映此更改来完成此操作 您如何着手创建一个数据库,该数据库考虑到小部件上的属性是流动的,并且可以随小部件的不同而变化 理想情况下,小部件属性应该是用户可以根据其偏好和需要定义的内容我会有一
理想情况下,小部件属性应该是用户可以根据其偏好和需要定义的内容我会有一个小部件表和一个小部件属性表。例如:
Widgets
- Id
- Name
WidgetAttributes
- Id
- Name
Name Properties
Widget1 Attr1:Value1;Attr2:Value2;...etc
然后,您将有另一个表,其中包含哪些小部件具有哪些属性:
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表中的行,而不是修改小部件表的结构,向小部件添加属性。我将有一个小部件表和一个小部件属性表。例如:
Widgets
- Id
- Name
WidgetAttributes
- Id
- Name
Name Properties
Widget1 Attr1:Value1;Attr2:Value2;...etc
然后,您将有另一个表,其中包含哪些小部件具有哪些属性:
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表中的行,而不是通过修改小部件表的结构来向小部件添加属性。casperOne正在展示方法,尽管我个人会为属性值再添加一个表,结果是
Widgets
-WidgetID (pk)
-Name
WidgetAttributes
-AttributeID (pk)
-Name
WidgetHasAttribute
-WidgetID (pk)
-AttributeID (pk)
WidgetAttributeValues
-ValueID (pk)
-WidgetID
-AttributeID
-Value
为了检索结果,您需要联接表并执行聚合连接,因此最终的数据如下(例如):
然后,您可以在业务逻辑层中拆分属性字符串并根据需要使用
关于如何加入数据的建议:
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)
您可以阅读有关聚合连接的更多信息
就性能而言,只要确保对所有经常读取的列进行索引,就不会有问题——也就是说
- 所有ID列,因为它们将在join子句中进行比较
- WidgetAttributes.Name和WidgetAttributeValues.Value,因为它们将连接在一起
Widgets
-WidgetID (pk)
-Name
WidgetAttributes
-AttributeID (pk)
-Name
WidgetHasAttribute
-WidgetID (pk)
-AttributeID (pk)
WidgetAttributeValues
-ValueID (pk)
-WidgetID
-AttributeID
-Value
为了检索结果,您需要联接表并执行聚合连接,因此最终的数据如下(例如):
然后,您可以在业务逻辑层中拆分属性字符串并根据需要使用
关于如何加入数据的建议:
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)
您可以阅读有关聚合连接的更多信息
就性能而言,只要确保对所有经常读取的列进行索引,就不会有问题——也就是说
- 所有ID列,因为它们将在join子句中进行比较
- WidgetAttributes.Name和WidgetAttributeValues.Value,因为它们将连接在一起