2

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

对于给定的对象实例,大多数属性大部分时间都将为

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

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

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

4

1 回答 1

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. 值(真或假)
于 2012-08-30T21:47:19.130 回答