15
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SQLアンチパターン Entity Attribute Value

Last updated at Posted at 2020-07-26

Entity Attribute Value

可変属性をサポートするなどの柔軟な設計を目指したことに起因するアンチパターン。

テーブル設計

Entity Attribute Value(以下EAV)では次のような項目を持ったテーブルが設計される。

名称 役割
Entity 親テーブルに対応した外部キーを格納
Attribute カラム名に相当する属性名を指定
Value 属性の値

Book

book_id
1

BookAttribute

book_id attr_name attr_value
1 name エンジニアになろう
1 status used
1 creater USER1
1 price 3520
1 page 450
1 release_date 2020/9/24
1 review 3.5
1 size 5x20x25cm

メリット

  • テーブルの列数を削減できる
  • 新規の属性を追加する際に列数を増加しなくて良い
  • 属性が存在しない列にNULLが入りNULLだらけのテーブルにならない
  • データベースの構造は単純になる

デメリット

  • データの取得が冗長化する
  • 特定の属性にNOT NULL制約を設定できない
  • データ型を使用できない
  • 外部制約キーを使用できない
  • 動的に属性名が増えるため整合性が担保しづらい

データの取得が冗長化する

Book(EAVを使用していない)

book_id name status creater
1 エンジニアになろう used USER1

BookAttribute(EAVを使用)

book_id attr_name attr_value
1 name エンジニアになろう
1 status used
1 creater USER1

「作成者(creater)」を取得したい場合、EAV設計をしない設計では「creater」が存在して入れば1文で必要なデータを取得できるが、EAV設計の場合では「attr_name」で必要なデータを条件として取得する必要がある

特定の属性にNOT NULL制約を設定できない

EAV設計の場合、特定の属性(「attr_name」の「creater」など)に対して個別にNOT NULL制約をつけることができない。

データ型を使用できない

Attribute複数のデータを格納するためデータ型を使用できない。
時間や数値が混在するため文字列として指定することが基本となる。
また同じ日付を格納するにしても「2020−1−1」と登録するパターンや「2020/1/1」と登録するパターンなどが混在しデータの整合性が取りづらい

外部制約キーを使用できない

「attr_name」のうちの1つの属性に対してに外部キーを設定してしまうと全ての属性に制約がかかってしまうため使用できない

動的に属性名が増えるため整合性が担保しづらい

book_id attr_name attr_value
1 name エンジニアになろう
1 book_name エンジニアになろう
1 status used
1 creater USER1

属性名が動的に増える可能性があるため整合性が担保しづらい。
上記のように「name」と「book_name」のように同じ本の名称を表す属性が複数登録されてしまうことがあるためあらかじめ属性名を統一して定義しておかないと整合性の担保が難しい。

次回

ポリモーフィック関連

参考文献

SQLアンチパターン

参考文献.jpg

15
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?