SQL中存储多个可空布尔的策略

时间:2012-08-30 21:36:26

标签: sql sql-server

我有一个对象(碰巧是C#),有20个属性可以为空的布尔值。可能会有几百万个此类对象持久存储到SQL数据库(当前是SQL Server 2008 R2,但将来可能需要支持MySQL)。实例本身相对较大,因为它们包含大约一段文本以及一些其他不相关的属性。

对于给定的对象实例,大多数时候大多数属性都是 null

当用户搜索此类对象的实例时,他们将选择1-3个可以为空的布尔属性,并搜索其中至少有一个属性为非空(OR搜索)的实例。

我的第一个想法是将对象持久化到一个表,其中可空的BIT列表示可以为空的布尔属性。但是,此策略将需要每个BIT列一个索引,以避免在搜索时执行表扫描。此外,每个指数不会特别具有选择性,因为每个指数只有三个可能的值。

有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

出于性能原因,我建议您将表拆分为两个表。

使用用于索引的位字段创建主键。有另一个表有额外的数据(如段落)。使用第一个用于WHERE条件,加入第二个以获取所需数据。类似的东西:

select p.*
from BitFields bf join
     Paragraph p
     on bf.bfid = p.bfid
where <conditions on the bit fields>

对于一堆二进制/三元字段,我不认为索引会有多大帮助,因此查询引擎将采用全表扫描。如果在一个表中放入位字段,则可以将表存储在内存中,并获得良好的性能。

另一种方法是将字段存储为名称值对。如果你真的有很多这样的字段(比如数百或数千)并且在给定的行中只使用了少数(比如十几个),那么实体 - 属性 - 值(EAV)结构可能会更好。这是一个包含三个重要列的表:

  1. 实体ID(上面我称之为bfid)。
  2. 属性ID(特定属性)
  3. 价值(真或假)