web-dev-qa-db-ja.com

ベストプラクティス、150以上の列を持つMySQLテーブル、多くのnull

何千ものプロパティのプロパティデータを格納するテーブルがあり、すべてフィードから取得しています。 (少なくとも1日に1回更新)。

私は確かにデータベースの専門家ではないので、プロパティテーブルの作成に取り組むための最良の方法についてのガイダンスをいただければ幸いです。課題は、各プロパティに含まれる属性と含まれない属性のLOTがたくさんあることです。各属性値は潜在的に一意であるため、リレーショナルテーブルは、それが何らかの利点を提供するようには見えません。

現在、テーブルの計画は単純で、NULLの可能性のある列が多数ある幅の広いテーブルを作成しています。例えば:

id - int(not null)
date - datetime(not null)
attribute1 - varchar(null)
attribute2 - varchar(null)
attribute3 - int(null)
attribute4 - bool(null)
ect..

これを設定するより良い方法はありますか?各属性はプロパティに一意に関連付けられているため、1つのテーブルにすべてを保持することは意味があります。

多くの列がNULLであっても、その数の列があると、そのテーブルに数千のレコードが存在するときに問題が発生しますか?毎日、このテーブルでいくつかの選択クエリを選択して、毎回数百から数千のレコードを返す必要があります。

何を研究すべきかについてのアドバイスや指示は大歓迎です!

5
turnfire

Entity-Attribute-Value 設計。一般的な概念は、すべてのデータを次のような形の非常に長くて狭いテーブルに配置することです。

CREATE TABLE dbo.PropertyAttributes
(
PropertyID   INT NOT NULL
             REFERENCES dbo.Properties(PropertyID),
AttributeID  INT NOT NULL
             REFERENCES dbo.Attributes(AttributeID),
StringValue  NVARCHAR(1024),
NumericValue DECIMAL(16,4),
DateValue    SMALLDATETIME,
ModifiedDate SMALLDATETIME NOT NULL
             DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (PropertyID, AttributeID)
);

次に、属性に関するメタデータを保存します。少なくとも、次のようなものが必要です。

CREATE TABLE dbo.Attributes
(
AttributeID INT PRIMARY KEY,
PropertyID  INT NOT NULL 
            REFERENCES dbo.Properties(PropertyID),
[Name]      NVARCHAR(32) NOT NULL UNIQUE,
DataTypeID  TINYINT NOT NULL -- 1 = string, 2 = numeric, 3 = date
);

この方法を採用すると、データに新しい属性が表示されたときにデータベース構造を変更してデータを格納する必要がなく、作成した新しい列にアクセスするために新しいクエリを作成する必要がないため、いくつかの利点があります。

生活の他の側面と同様に、これらの利点にはトレードオフが伴います。非常に広いビューを作成するには、テーブルをPivotする必要があります。これは、実行するのにコストのかかるクエリになる可能性があります。

ここにかなり投稿しているアーロン・バートランド このアプローチでの彼の経験について説明しています 2009年。これは今日でも読む価値があります。

属性を確認し、最も関連性の高い属性を分解する可能性があるMDCCLの提案は適切です。最も一般的に使用される属性を基本のプロパティテーブルに移動して、EAVテーブルのピボットの頻度を減らします。

4
Mark Iannucci