2

null 許容ブール値である約 20 個のプロパティを持つオブジェクト (たまたま C#) があります。おそらく数百万のそのようなオブジェクトが SQL データベースに永続化されるでしょう (現在は SQL Server 2008 R2 ですが、MySQL は将来サポートされる必要があるかもしれません)。インスタンス自体は、約 1 段落のテキストとその他の無関係なプロパティを含むため、比較的大きくなります。

特定のオブジェクト インスタンスでは、ほとんどの場合、ほとんどのプロパティがnullになります。

ユーザーがそのようなオブジェクトのインスタンスを検索する場合、おそらく 1 ~ 3 個の null 許容ブール プロパティを選択し、それらの 1 ~ 3 個のプロパティの少なくとも 1 つが非 null であるインスタンスを検索します (OR 検索)。

私が最初に考えたのは、null 可能なブール値プロパティを表す null 可能な BIT 列を持つ単一のテーブルにオブジェクトを永続化することです。ただし、この戦略では、検索時にテーブル スキャンを実行しないように、BIT 列ごとに 1 つのインデックスが必要です。さらに、インデックスごとに可能な値が 3 つしかないため、各インデックスは特に選択的ではありません。

この問題にアプローチするより良い方法はありますか?

4

1 に答える 1

1

パフォーマンス上の理由から、テーブルを 2 つのテーブルに分割することをお勧めします。

インデックスに使用されるビット フィールドで主キーを作成します。追加データ (段落など) を持つ別のテーブルを用意します。最初の条件を WHERE 条件に使用し、2 番目の条件に参加して必要なデータを取得します。何かのようなもの:

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

多数のバイナリ/ターナリ フィールドがある場合、インデックスがあまり役に立たないと思うので、クエリ エンジンはフル テーブル スキャンに頼ることになります。ビット フィールドを 1 つのテーブルに配置すると、テーブルをメモリに格納でき、パフォーマンスが向上します。

別の方法は、フィールドを名前と値のペアとして保存することです。そのようなフィールドが実際にたくさんあり (たとえば、数百または数千)、特定の行で使用されるフィールドがごくわずか (たとえば、12 個程度) である場合は、エンティティー属性値 (EAV) 構造がより適切に機能する可能性があります。これは、3 つの重要な列を持つテーブルです。

  1. エンティティ ID (上記で bfid と呼んでいるもの)。
  2. 属性 ID (特定の属性)
  3. 値 (真または偽)
于 2012-08-30T21:47:19.130 に答える