SQL Server 数据库的现状
有一个包含以下列的表条目:
- 条目 ID (int)
- 条目名称 (nvarchar)
- 入口大小 (int)
- EntryDate(日期时间)
此外,应该可以为条目保存额外的元数据。这些元数据的名称和值应该可以自由选择,并且应该可以在不改变数据库表结构的情况下动态添加它们。每个元数据键可以是以下数据类型之一:
- 文本
- 数值
- 约会时间
- 布尔值(真/假)
因此,有一个表 DataKey 用以下列表示元数据名称和数据类型:
- DataKeyID (int)
- 数据键名 (nvarchar)
- DataKeyType (smallint) 0:文本;1:数字;2:日期时间;3:位
根据元数据键的数据类型,可以在表中插入 Entry 和 DataKey 值的每个组合的 DataValue。对于每种数据类型,都有一个可为空的值列。此表具有以下列:
- 数据值 ID (int)
- EntryID (int) 外键
- DataKeyID (int) 外键
- TextValue (nvarchar) 可以为空
- NumericValue (float) Nullable
- DateValue(日期时间)可为空
- 布尔值(位)可为空
数据库结构图:
目标
目标是检索满足 WHERE 子句中规范的条目列表。像下面的例子:
假设:
- 元数据键 KeyName1 是文本
- 元数据键 KeyName2 是 DateTime
- 元数据键 KeyName3 是数字
- 元数据键 KeyName4 是布尔值
询问:
... WHERE (KeyName1 = „Test12345“ AND KeyName2 BETWEEN ’01.09.2012 00:00:00’ AND
’01.04.2013 23:59:00’) OR (KeyName3 > 15.3 AND KeyName4 = True)
目标是以一种非常有效的方式进行这些查询,同时使用大量数据,例如
- 条目数 > 2.000.000
- 50 到 100 或可能 > 100 之间的数据键数
- 每个条目至少指定值的子集,或者也可能是每个键的值 (2.000.000 * 100)
问题
第一个问题是在构建查询时出现的。通常查询需要具有可在 WHERE 子句中使用的列的集合。在这种情况下,查询中使用的列也是表 DataKey 中的条目,以便能够动态添加元数据而无需更改数据库表结构。在研究期间,已经找到了在运行时使用 PIVOT 表技术的解决方案。但事实证明,当数据库中有大量数据时,这种解决方案非常慢。
问题
- 是否有更有效的方法或结构来为此目的保存数据?
- 如何满足上面列出的要求,以及查询时的性能和时间消耗?
这是一个带有描述的数据库结构和一些示例数据的 sql fiddle:http ://www.sqlfiddle.com/#!3/d1912/3