我需要存储一个包含大量用户定义字段的大表(数百万或行)(在编译时不知道,但可能大约有20到40个自定义字段)。能够根据这些自定义字段查询数据非常重要(性能方面):即“选择此属性具有该值的行,该属性是该值,等等”。每个查询都有大约20到30个WHERE子句。
到目前为止我的想法:
每次实施新用户字段时都要更改数据库架构。将每个用户定义的字段保留为表中的列。在每个自定义创建的列上添加和维护索引。如何正确构建这些索引是一个大问题,因为我不知道在WHERE查询中将使用哪些属性(列)。
将自定义字段存储为XML类型列。据我所知,从SQL2005我可以在XML类型列中查询XML内部。不过对表现不太确定。
Entity Attribute Value。这就是我现在使用的,但这很痛苦。
有什么建议吗?
编辑: 对我的要求做了一些澄清。我有一张表,有4千万到5千万行(比方说)ID号和与这些ID相关的各种属性。
假设其中有2千万的“CustomAttribute1”等于2,则500万的“CustomAttribute2”等于“是”,300万的“CustomAttribute20”等于“否”
I need a FAST method of returning all IDs where:
1. CustomAttribute1 = 2
2. CustomAttribute2 = 'Yes'
3. CustomAttribute4 = null
4. CustomAttribute20 != 'No'
etc...
我们将其作为EAV实现:选择查询是实现和维护的噩梦,返回结果需要很长时间,而且最令人厌恶的是,即使对于小数据量,数据库也会扩展到大尺寸,这很奇怪EAV基本上是对数据进行规范化,但我假设所有索引占用了大量空间。
答案 0 :(得分:4)
您似乎已列出了可用选项。 EAV可能是查询的痛苦(而且速度很慢,取决于您想要同时搜索多少个标准),但它往往是最“理智”且与RDBMS无关的实现。
修改架构是一个禁忌......显然它可以做到,但这种做法是令人憎恶的。我不赞成。
XML选项是一种解决方案,SQL Server可以在结构内部进行查询。我不确定其他RDBMS,你没有列出你在帖子或标签中使用的那个。
如果您要同时查询许多属性(例如,20+),那么我可能会建议使用XML解决方案来限制您必须进行的连接数。除此之外,我会坚持使用EAV。
答案 1 :(得分:0)
您可以使用XML列表示所有用户定义的字段,例如
“但我不确定这样做会对性能产生什么影响,但在我看来,这绝对是在数据库中处理UDF的最佳方式。”
<UDF>
<Field Name="ConferenceAddress" DBType="NVarChar" Size="255">Some Address</Field>
<Field Name="ConferenceCity" DBType="NVarChar" Size="255">Some City</Field>
...etc
</UDF>
然后我要做的是在表上放置一个触发器,以便在更新列时重新创建表的视图,该视图将xml值作为视图上的列拉出。在重新创建过程中锁定视图等以防止应用程序端访问错误。
然后我将创建一个用于更新XML的存储过程,以便它可以用于遵循用户定义的字段xml格式的任何XML列,例如,插入/更新/删除/ GET
GetUDFFieldValue AddUDFField UpdateUDFField DeleteUDFField
- 共享参数 表名 的ColumnName (例如,使用动态SQL通过X列名从X表中获取XML,使其对所有UDF字段都是通用/通用的)
以下是一篇关于Sql Server 2005的XML性能优化的文章(在新版本中没有看到相同的版本):
http://technet.microsoft.com/en-us/library/ms345118(v=sql.90).aspx
最后:
您确定甚至需要RDBMS吗? NoSql更适合用户生成的字段,我甚至可以考虑使用NoSql和Sql Server。