SQL Server データベースの現状
次の列を持つテーブル エントリがあります。
- EntryID (整数)
- EntryName (nvarchar)
- EntrySize (整数)
- EntryDate (日時)
さらに、エントリの追加のメタデータを保存する可能性があるはずです。これらのメタデータの名前と値は自由に選択でき、データベースのテーブル構造を変更せずに動的に追加できる必要があります。各メタデータ キーは、次のデータ型のいずれかになります。
- 文章
- 数値
- 日付時刻
- ブール値 (True/False)
したがって、次の列を持つメタデータ名とデータ型を表すテーブル DataKey があります。
- DataKeyID (int)
- DataKeyName (nvarchar)
- DataKeyType (smallint) 0: テキスト。1: 数値。2: 日時。3: ビット
Entry 値と DataKey 値の各組み合わせのテーブル DataValue には、メタデータ キーのデータ型に応じて挿入できます。データ型ごとに、NULL 値を許容する列が 1 つあります。このテーブルには次の列があります。
- DataValueID (整数)
- EntryID (int) 外部キー
- DataKeyID (int) 外部キー
- TextValue (nvarchar) Nullable
- NumericValue (float) Nullable
- DateValue (日時) Nullable
- BoolValue (ビット) Nullable
データベース構造のイメージ:
目標
対象は、WHERE句のように仕様を満たすエントリのリストを取得することです。次の例のように:
予測:
- メタ データ キー KeyName1 はテキストです
- メタ データ キー KeyName2 は DateTime です
- メタデータ キー KeyName3 は数値です
- メタデータ キー KeyName4 はブール値です
クエリ:
... WHERE (KeyName1 = „Test12345“ AND KeyName2 BETWEEN ’01.09.2012 00:00:00’ AND
’01.04.2013 23:59:00’) OR (KeyName3 > 15.3 AND KeyName4 = True)
目標は、これらのクエリを非常に効率的な方法で実行することです。また、次のような大量のデータも使用します。
- エントリ数 > 2.000.000
- 50 から 100 の間、または 100 を超える可能性のあるデータ キーの数
- エントリごとに少なくとも指定された値のサブセット、または各キーの値 (2.000.000 * 100)
問題
最初の問題は、クエリを作成するときに発生します。通常、クエリには、WHERE 句で使用できる列を含むセットが必要です。この場合、クエリで使用される列はテーブル DataKey のエントリであり、データベース テーブル構造を変更せずにメタデータを動的に追加できます。調査中に、実行時に PIVOT テーブル手法を使用して解決策が見つかりました。しかし、データベースに大量のデータがある場合、このソリューションは非常に遅くなることが判明しました。
質問
- この目的のためにデータを保存するためのより効率的な方法または構造はありますか?
- クエリ時のパフォーマンスと時間の消費に関しても、上記の要件を満たすにはどうすればよいでしょうか?
これは、記述されたデータベース構造といくつかのサンプルデータを使用したSQLフィドルです: http://www.sqlfiddle.com/#!3/d1912/3