私は車と呼ばれるテーブルを持っていますが、各車には何百もの属性があり、それらは時間の経過とともに増加し続けます (馬力、トルク、エアコン、電動ウィンドウなど...) 私のテーブルには各属性が列として含まれています。何千もの行と何百もの列がある場合、それは正しい方法ですか? また、各属性を列にして、高度な検索/フィルタリングを容易にしました。
MySQLデータベースの使用。
ありがとう
これは興味深い質問です。答えは、特定のデータ モデルと実装によって異なる場合があります。この場合の最も重要な要素はデータ密度です。
各行のうち、実際に埋まっているのは平均でどれくらいですか?
あなたが言及したケースを使用して、いくつかのシミュレーションを行いましょう。
最初のケースであるscope partitionのアイデアは、スコープまたは使用法に基づいてパーティションを実装することです。使用法によるパーティション分割の例として、最も多く取得されるフィールドがモデル、年、メーカー、および色であるとしましょう。これらのフィールドは、車両のみを識別する ID フィールドの所有者であるメインの [CAR] テーブルを構成する場合があります。エンジン、馬力、トルク、シリンダーも時々検索に使用されますが、それほど頻繁ではないとしましょう。これらは、外部キーである CAR_ID フィールドの存在によって最初のテーブルに関連付けられているセカンダリ テーブル [CAR_INFO_1] に存在する場合があります。必要な数のパーティションを作成して続行します。
利点: クエリがより簡単になります。共同クエリを実行すると (たとえば、VIEW 内で)、車両に関するすべての情報を結合できます。
欠点:メンテナンス。新しい各フィールドはモデル自体に実装する必要があり、必要なフィールドが実際に格納されている場所を見つける (またはビュー内で抽象化する) には、更新されたデータ モデルが必要です。
メタデータ形式ははるかに洗練されていますが、より多くのデータベース エンジンを必要とします。詳細については、@JayC と @Nitzan Shaked の回答を確認してください。
利点: 100% のデータ密度。空の Data 値を持つことはありません。また、メンテナンス - 新しい属性は、メタデータ識別子テーブルに行として追加することによって作成されます。データ構造もそれほど複雑ではありません。
欠点: 複雑なクエリと、より複雑な実行プラン。2010 年に製造された青色の Ford 車がすべて必要だとします。最初のケースでは非常に簡単です。
SELECT * FROM CAR WHERE Model='Ford' AND Year='2010' AND Color='Blue'
メタデータ構造化モデルに対する同じクエリ:
この2つのテーブルが存在すると仮定すると、
CAR_METADATA_TYPE
ID DESC
1 'Model'
2 'Year'
3 'Color'
と
CAR_METADATA [CAR_ID], [METADATA_TYPE_ID], [VALUE]
クエリ自体は次のようになります。
SELECT * FROM CAR, CAR_METADATA [MP1], CAR_METADATA [MP2], CAR_METADATA [MP3]
WHERE MP1.CAR_ID = CAR.ID AND MP1.METADATA_TYPE_ID = 1 AND MP1.Value='Ford'
AND MP2.CAR_ID = CAR.ID AND MP2.METADATA_TYPE_ID = 2 AND MP2.Value='2010'
AND MP3.CAR_ID = CAR.ID AND MP3.METADATA_TYPE_ID = 3 AND MP3.Value='Blue'
したがって、それはすべてあなたのニーズに依存します。しかし、あなたの場合、私の提案はメタデータ形式です。
(ただし、最初にモデルのクリーンアップを行います。繰り返しフィールドはなく、Color1、Color2、Color3 などのインライン フィールドではなく、独自のテーブルに 1:N データを配置します。この種のもの;))
明らかな疑問は、なぜ car_attrs(car, attr, value) テーブルを持たないのかということだと思います。各属性は行です。ほとんどのクエリは、このフォームを使用するように書き直すことができます。
すべてが機能に関するものである場合は、テーブルを作成し、すべての機能を行としてfeatures
リストし、何らかの自動 ID を付与し、テーブルと、車を機能に関連付けるテーブルの両方への外部キーを持つを作成します。関係に関連付けられた値 (1 人の乗客の電動シートなど)。car_features
cars
features
属性を変更したことがある場合は、それらを 1 つの列の XML BLOB またはテキスト構造に格納することを検討してください。この構造はリレーショナルではありません。最も重要な属性は追加の列に複製されるため、Blob は SQL クエリから検索できないため、それらを検索するクエリを作成できます。これにより、そのテーブルの列の量が削減され、データベース スキーマを変更せずに拡張できるようになります。
他の人が提案したように、テーブル内のすべての属性が必要な場合は、属性テーブルを使用してそれらを定義します。次に、要件とアプリケーションのニーズによって異なります。