動的エントリに関するデータベース設計-1行ですか?それとも複数行ですか?
質問
私はサイドプロジェクトのデータベーススキーマを設計しようとしましたが、自分が満足できるものを作成することができませんでした。データアクセスにLINQでASP.Netを使用しています:
ユーザーが最大10個の「アイテム」を指定できるようにします。それぞれに2つの数値プロパティと1つの参照プロパティ、アイテム名があります。
このエントリを1行に入れると、30以上の列(最小)に簡単に等しくなります。 item_1_name(参照) item_1_weight item_1_volume item_2_name ...など...
各プロパティは基本的に1〜400以上の範囲にあるため、これらの列を参照テーブルに単純に変更することはできません。
また、ユーザーがエントリに1項目のみを入れると決めた場合、そのデータのオブジェクトを作成する方法はLINQのように静的になると考えたので、プロパティとwhatnotがNULLかどうかを確認する必要がありますそれに応じて動作します。また、エントリで許可されているアイテムの数を増やしたい場合、作業するのは頭痛の種になります。
私が考えたもう1つのオプションは、単に各アイテムの行を作成し、それをエントリIDで結び付けることです。そのため、本質的にnullエントリはありませんでしたが、テーブルは天文学的に深くなりますが、幅はあまり広くなく、奇数の列は5つしかありません。
デザインで見落としているものがありますか/これを行うためのはるかに優れた効率的な方法がありますか?
編集:それが天文学的に成長すると言うとき、私はこの意味でそれを意味します:ユーザーはエントリを作成でき、各エントリにはほとんどの場合アイテムのグループがあります。したがって、サイトに1日に1つのエントリを作成するとします。最大3つのアイテムのグループ(10)があり、その1つのエントリに対して30アイテムに相当します。そのレートで1週間毎日エントリを作成すると、その単一のユーザーに対して210行を持つことができます。
解決
後者の設計をお勧めします。5つの列を持つ1つの従属テーブルを作成します。
CREATE TABLE Items (
user_id INTEGER NOT NULL,
item_id INTEGER NOT NULL DEFAULT 1,
numeric_property1 INTEGER,
numeric_property2 INTEGER,
referential_property INTEGER,
PRIMARY KEY (user_id, item_id),
FOREIGN KEY (user_id) REFERENCES Users(user_id)
ON DELETE CASCADE,
FOREIGN KEY (item_id) REFERENCES num_items(item_id),
FOREIGN KEY (referential_property) REFERENCES some_other_table(some_column)
);
上記のテーブル num_items
を表示します。最大で10個のアイテムにユーザーを制限する場合は、1〜10の数字が含まれます。
CREATE TABLE num_items (item_id INTEGER NOT NULL );
INSERT INTO num_items (item_id)
VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
この設計の利点は、特定のユーザーが持っているアイテムの数を COUNT()
にしたり、 MIN()
やのようなものを簡単に計算できることです。特定のプロパティに対してMAX()
を使用すると、参照プロパティなどに外部キーを適用できます。
一部のデータベースには、複合主キーの2番目の部分(この場合は item_id
)を自動インクリメントとして宣言する機能があるため、 entity_id
ただし、 item_id
を省略すると、次の未使用の値が自動的に取得されます(ただし、ギャップを削除しても埋められません)。使用しているデータベースのブランドを明記しないため、この機能を理解するためにあなたに任せます。
編集: Tony Andrewsが答えで述べているように、行の数は問題ではありません。どのブランドのデータベースを使用するつもりかを述べることはありませんが、MS Accessのような特に脆弱な製品を選択しない限り、数百万行を簡単に処理するためにデータベースに頼ることができます。インデックスを適切に選択し、それらのインデックスを使用するクエリを作成する場合、効率は問題になりません。
他のヒント
単一のアイテムテーブルを使用:
userId、itemIndex、isReference、numericValue、referenceValue
これにより、ユーザー999のitem_3_nameの値は次のように変換されます
999,3、true、null、value
特定の制約を自分で実施する必要があります。ユーザーごとの最大アイテム数など
適切なデータベース設計では、各ユーザー/アイテムを別々の行に保存します。これにより、作業がはるかに簡単になり、10項目の任意の制限が削除されます。 「天文学的に深く」なるとは言いませんが、約10 x(ユーザー数)の行があります。