可扩展数据库模式 - 如何存储可扩展属性值

时间:2011-07-20 20:26:46

标签: sql database-design database-schema

我们正在使用SQL Server 2008,其中一个要求是在为系统定义的实体上具有可扩展的用户定义属性。例如,我们可能有一个名为Doctor的实体,我们希望系统的管理员能够定义通常不在系统中的额外属性。很可能需要这些属性作为链接父表或连接表的查询条件。

将有表定义属性(名称,描述,类型)等等,但我的问题是存储实际数据值。

我不是DBA(只是假装是一个程序员)但我的第一个想法是将它们存储在一个通用列中作为

nvarchar(450)

这将覆盖大多数基本类型并仍然允许索引,但我认为我会遇到很多转换类型问题(转换为日期,数字等)以及异常查询问题,因为一切都是nvarchar

所以,我最近的想法是为我们支持的每种数据类型创建一个列:

ColNVarCharData
nvarchar(450) 

ColBitData
bit

ColIntData
int

..等等

当用户定义extendable属性时,他们会选择一种数据类型,然后我们会在该列中为该类型存储属性值。例如,如果他们选择了int,则数据值将存储在ColIntData中,而其他两列在此示例中将为null。

我认为这解决了转换问题,而不是将每个属性存储为泛型类型。另外,我可以根据所使用的查询,根据需要为每种类型添加索引。

我倾向于使用它,但想知道是否有其他人有任何建议。我简明地看了一下XML数据类型,但“架构”可能会经常发生变化,所以我认为这更适合。

2 个答案:

答案 0 :(得分:2)

以下是与该主题相关的一些SO问题/答案。

答案 1 :(得分:0)

根据@gbn在评论中发给我的链接,我认为这是一个有效的答案(摘自WIKI链接):

价值

将所有值强制转换为字符串,如上面的EAV数据示例所示,会产生一种简单但不可扩展的结构:如果想要对值和索引执行任何操作,则需要进行常量数据类型的转换在EAV表的值列上基本没用。此外,将大型二进制数据(例如图像)以Base64编码形式存储在与小整数或字符串相同的表中是不方便的。因此,较大的系统对每种数据类型(包括二进制大对象,“BLOBS”)使用单独的EAV表,其中给定属性的元数据标识将在其中存储其数据的EAV表。这种方法实际上非常有效,因为用户选择使用的给定类或表单的适度数量的属性元数据可以很容易地缓存在内存中。但是,如果更改了属性的数据类型,则需要将数据从一个表移动到另一个表。 (这种情况不会经常发生,但可以像在数据库模式设计中那样在元数据定义中进行错误。)