可扩展数据库模式 - 如何存储可扩展属性值
Posted
技术标签:
【中文标题】可扩展数据库模式 - 如何存储可扩展属性值【英文标题】:Extendable Database Schema - How to store the extendable attribute values 【发布时间】: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 子表?而且也可以搜索...现在定义“维护工作”:-) 【参考方案1】:这里只是一些与主题相关的 SO 问题/答案。
One Two Three【讨论】:
【参考方案2】:根据@gbn 在 cmets 中发给我的链接,我认为这是一个有效的答案(取自 WIKI 链接):
价值
将所有值强制转换为字符串,就像上面的 EAV 数据示例一样,会产生一个简单但不可扩展的结构:如果想要对这些值和索引做任何事情,则需要常量数据类型的相互转换在 EAV 表的值列上基本上是无用的。此外,不方便将大型二进制数据(例如图像)以 Base64 编码形式存储在与小整数或字符串相同的表中。因此,较大的系统为每种数据类型(包括二进制大对象,“BLOBS”)使用单独的 EAV 表,给定属性的元数据标识将存储其数据的 EAV 表。这种方法实际上非常有效,因为用户选择使用的给定类或表单的适量属性元数据可以很容易地缓存在内存中。但是,如果属性的数据类型发生更改,则需要将数据从一个表移动到另一个表。 (这并不经常发生,但元数据定义中可能会出现错误,就像在数据库模式设计中一样。)
【讨论】:
以上是关于可扩展数据库模式 - 如何存储可扩展属性值的主要内容,如果未能解决你的问题,请参考以下文章