【发布时间】:2011-07-20 20:26:46
【问题描述】:
我们使用的是 SQL Server 2008,其中一项要求是在为系统定义的实体上具有可扩展的用户定义属性。例如,我们可能有一个名为 Doctor 的实体,我们希望系统管理员能够定义通常不在系统中的额外属性。这些属性很可能需要作为链接父表或联接表的查询条件。
会有定义属性(名称、描述、类型)等的表格,但我的问题是关于实际数据值的存储。
我不是 DBA(只是一个伪装成 DBA 的程序员),但我的第一个想法是将它们存储在一个通用列中作为
nvarchar(450)
这将涵盖大多数基本类型并且仍然允许索引,但我认为我会遇到很多转换类型问题(转换为日期、数字等)以及不寻常的查询问题,因为一切都是 nvarchar .
所以,我最近的想法是为我们支持的每种数据类型创建一个列:
ColNVarCharData
nvarchar(450)
ColBitData
bit
ColIntData
int
..等等
当用户定义了可扩展属性时,他们会选择一种数据类型,然后我们会在该列中存储该类型的属性值。例如,如果他们选择 int,则数据值将存储为 ColIntData,而在此示例中,其他两列将为 null。
我认为这解决了转换问题,而不是将每个属性存储为通用类型。此外,我可以根据使用的查询为每种类型添加索引。
我倾向于使用它,但想知道是否有人有任何建议。我简要地查看了 XML 数据类型,但“模式”可能会经常更改,所以我认为这更合适。
【问题讨论】:
-
使用此方法会有额外的开销,因为您必须从参考表中查找数据类型以及属性 ID
-
这是一个“EAV”提案。请参阅en.wikipedia.org/wiki/Entity-attribute-value_model 了解替代方案。它通常是一种 SQL 反模式。鉴于您的客户群,您当然可以预先捕获大部分模型......
-
@gbn ,感谢您的链接,读起来很好。是的,我们可以预先捕获大部分模型。这将用于在系统到位后添加的异常值或新数据点,以帮助减少维护工作的需要。
-
@Jon Raynor:就个人而言,我会接受维护打击。如果您提前计划,您应该能够通过知道快速添加新列所需的更改来满足它。您是否想要在 EAV 中使用 CSV,因为它们确实需要一个新的 1:n 子表?而且也可以搜索...现在定义“维护工作”:-)
标签: sql database-design database-schema