我有一个对象(碰巧是C#),有20个属性可以为空的布尔值。可能会有几百万个此类对象持久存储到SQL数据库(当前是SQL Server 2008 R2,但将来可能需要支持MySQL)。实例本身相对较大,因为它们包含大约一段文本以及一些其他不相关的属性。
对于给定的对象实例,大多数时候大多数属性都是 null 。
当用户搜索此类对象的实例时,他们将选择1-3个可以为空的布尔属性,并搜索其中至少有一个属性为非空(OR搜索)的实例。
我的第一个想法是将对象持久化到一个表,其中可空的BIT列表示可以为空的布尔属性。但是,此策略将需要每个BIT列一个索引,以避免在搜索时执行表扫描。此外,每个指数不会特别具有选择性,因为每个指数只有三个可能的值。
有没有更好的方法来解决这个问题?
答案 0 :(得分:1)
出于性能原因,我建议您将表拆分为两个表。
使用用于索引的位字段创建主键。有另一个表有额外的数据(如段落)。使用第一个用于WHERE条件,加入第二个以获取所需数据。类似的东西:
select p.*
from BitFields bf join
Paragraph p
on bf.bfid = p.bfid
where <conditions on the bit fields>
对于一堆二进制/三元字段,我不认为索引会有多大帮助,因此查询引擎将采用全表扫描。如果在一个表中放入位字段,则可以将表存储在内存中,并获得良好的性能。
另一种方法是将字段存储为名称值对。如果你真的有很多这样的字段(比如数百或数千)并且在给定的行中只使用了少数(比如十几个),那么实体 - 属性 - 值(EAV)结构可能会更好。这是一个包含三个重要列的表: