2017-02-15 14 views
1

異なる種類の製品の情報をデータベースに格納する必要があるとします。ただし、これらの製品は仕様が異なります。リレーショナルデータベースの情報を拡張する最良の方法

  • 電話:CPU、RAM、ストレージ...
  • テレビ:たとえばサイズ、解像度...

我々はの欄に各仕様を保存したいですテーブル、およびすべての製品(タイプに関係なく)は異なるIDを持つ必要があります。それに準拠するため

、今私は(... ProductsPhonesProductsTV)(自動インクリメントIDを持つ)Productsという名前の一般的なテーブルと、製品の種類ごとに1つの従属テーブルを持っている仕様として校長とリンク外部キー。

テーブルProductsには1つの列(自動インクリメントID)があるため、このソリューションは効率的ではありません。

リレーショナルデータベースを使用してこの問題を解決する方がよいかどうかを知りたいと思います。

答えて

2

短い答えはノーです。リレーショナル・モデルは一次論理モデルであり、述語はエンティティー上では変更できますが、他の述部では変更できません。つまり、従属型とEAVモデルはサポートされていません。

EAVモデルはSQLデータベースでも使用できますが、EAV行の値フィールドのドメインは属性フィールドの値によって決まります(また、エンティティフィールドの値によってはよく)。実用的には、EAVモデルは照会および維持にとって非効率的である傾向がある。

PostgreSQLは、共通のスーパータイプテーブルを持たない独自の自動インクリメントIDを確保できる共有シーケンスをサポートしています。ただし、スーパータイプ・テーブルはFK制約のためにはまだ良い考えです。

あなたがなどTypeSerial numberCostWarranty durationNumber in stockWarehouseSupplier、などの共通の属性を保持するために、後でProductsテーブルのためのいくつかの用途を見出すことができる...

+0

可能であれば、私の答えがなぜリレーショナルでないのか分からないのですか? – Forklift

1

これは完全には関係ありませんが、テーブルをいくつか正規化してコード化するのは少し簡単です。電話のためのだから、

-- what are the products? 
Products (Id, ProductTypeId, Name) 

-- what kind of product is it? 
ProductTypes (Id, Name) 

-- what attributes can a product have? 
Attributes (Id, Name, ValueType) 

-- what are the attributes that come with a specific product type? 
ProductTypeAttributes (Id, ProductTypeId, AttributeId) 

-- what are the values of the attributes for each product? 
ProductAttributes (ProductId, ProductTypeAttributeId, Value) 

とテレビ:

あなたはこれらのテーブルを持つことができます

ProductTypes (1, Phone) -- a phone type of product 
ProductTypes (2, TV)  -- a tv type of product 

Attributes (1, ScreenSize, integer) -- how big is the screen 
Attributes (2, Has4G, boolean) -- does it get 4g? 
Attributes (3, HasCoaxInput, boolean) -- does it have an input for coaxial cable? 

ProductTypeAttributes (1, 1, 1) -- a phone has a screen size 
ProductTypeAttributes (2, 1, 2) -- a phone can have 4g 
-- a phone does not have coaxial input 
ProductTypeAttributes (3, 2, 1) -- a tv has a screen size 
ProductTypeAttributes (4, 2, 3) -- a tv can have coaxial input 
-- a tv does not have 4g (simple example) 

Products (1, 1, CoolPhone) -- product 1 is a phone called coolphone 
Products (2, 1, AwesomePhone) -- prod 2 is a phone called awesomephone 
Products (3, 2, CoolTV) -- prod 3 is a tv called cooltv 
Products (4, 2, AwesomeTV) -- prod 4 is a tv called awesometv 

ProductAttributes (1, 1, 6) -- coolphone has a 6 inch screen 
ProductAttributes (1, 2, True) -- coolphone has 4g 
ProductAttributes (2, 1, 4) -- awesomephone has a 4 inch screen 
ProductAttributes (2, 2, False) -- awesomephone has NO 4g 
ProductAttributes (3, 3, 70) -- cooltv has a 70 inch screen 
ProductAttributes (3, 4, True) -- cooltv has coax input 
ProductAttributes (4, 3, 19) -- awesometv has a 19 inch screen 
ProductAttributes (4, 4, False) -- awesometv has NO coax input 

これは完全には関係ない理由は、あなたはまだ値の型を評価する必要がありますということです(bool、intなど)を使用してコード内で意味のある方法で使用することができます。

+0

あなたのモデルは、SQLで有効ですが、ProductAttributes' 'で[値]列のドメインが' ProductTypeAttributeId'フィールドの値に行ごとに依存しているため、それは関係ありません。 1NFでは、リレーションの各コンポーネントに単一のドメインが必要です。たとえば、 'ProductAttributes(1、1、True)'は有効な行ではありませんが、外部キー制約を使用して防止することはできません。 EAVモデルでは、リレーショナルモデルで使用されているよりも高い形式のロジックが必要です。 – reaanb

+0

私は理解していると信じています。どのくらい正規化しようとしても、値がboolかintかどうかを判断するためにはいつも評価が必要です。純粋にリレーショナルとはみなされませんか? – Forklift

+1

はい、そうです。場合によっては、1NF以外のデータを表現するSQLの能力が実際には利点になる場合がありますが、矛盾を招かないように慎重に使用する必要があります。 – reaanb

1

がProductsテーブルを持つことは結構です。製品名、説明、コスト、価格などのすべてのタイプに共通するすべての列をそこに置くことができます。つまり、自動増分IDだけではありません。主キーとしてint型またはlong intの内部IDを持つことをお勧めします。別のフィールド「コード」を追加することもできますし、製品管理システムに共通する、ユーザが入力した、またはユーザーフレンドリーなものを呼び出すこともできます。検索条件またはクエリ条件で使用されている場合は、必ずインデックスを作成してください。

HTH

関連する問題