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,因为它们将连接在一起

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,因为它们将连接在一起

如果有大量小部件,这会导致性能问题吗?如果要显示1000个小部件,那么对于每个小部件,我们必须分别查询它们的属性。我不是db专家,所以不确定即使在一个SQL查询中,这是否会显著降低速度?@abdullah.ahmed:我不这么认为。对于一个数据库来说,数千条记录真是小菜一碟。如果有大量的小部件,这会导致性能问题吗?如果要显示1000个小部件,那么对于每个小部件,我们必须分别查询它们的属性。我不是db专家,所以不确定即使在一个SQL查询中,这是否会显著降低速度?@abdullah.ahmed:我不这么认为。一个数据库有数千条记录,真是小菜一碟。