DB設計でアンチパターン取り上げられてるEAV設計(Entity-Attribute-Value)の使用感。
気が向くたび更新。
EAV設計のデータ例
こんなやつ。
tbl
id | type | kind |
---|---|---|
001 | animal | 猫 |
002 | animal | 鳥 |
003 | musical instrument | ドラム |
004 | musical instrument | ギター |
tbl_attribute
id | attribute_name | attribute_value |
---|---|---|
001 | 武器 | 爪 |
001 | 特技 | 仕事の邪魔 |
002 | 武器 | クチバシ |
002 | 特技 | 飛ぶ |
003 | 敷居 | 高い |
004 | 敷居 | 普通 |
メリット
①列数減らせる
一つのテーブルで表現すると多分こうなる
id | type | kind | 武器 | 特技 | 敷居 |
---|---|---|---|---|---|
001 | animal | 猫 | 爪 | 仕事の邪魔 | NULL |
002 | animal | 鳥 | クチバシ | 飛ぶ | NULL |
003 | musical instrument | ドラム | NULL | NULL | 高い |
004 | musical instrument | ギター | NULL | NULL | 普通 |
②属性増えたら列増やさなくてよい
「誕生」という属性増やしたい場合
id | attribute_name | attribute_value |
---|---|---|
001 | 武器 | 爪 |
001 | 特技 | 仕事の邪魔 |
001 | 誕生 | 2012-01-01 |
002 | 武器 | クチバシ |
002 | 特技 | 飛ぶ |
002 | 誕生 | 2013-01-01 |
デメリット
①データ整合性保つのが難しい
日付箇所に日付じゃない値入れちゃったり、属性名に誤字あったりしてしまうことある。
id | attribute_name | attribute_value |
---|---|---|
001 | ああああ | 仕事の邪魔 |
001 | 誕生 | ああああ |
②データ抽出つらい
たくさんJOINしないといけない。10個の属性値抽出だと10個JOINしないといけない。
SELECT
tbl.kind
, tbl_attr_weapon.attribute_value AS 武器
, tbl_attr_skill.attribute_value AS 特技
FROM
tbl AS tbl
JOIN tbl_attribute AS tbl_attr_weapon
ON tbl.id = tbl_attr.id
AND attribute_name = '武器'
JOIN tbl_attribute AS tbl_attr_skill
ON tbl.id = tbl_attr.id
AND attribute_name = '特技'
;
③属性名や属性値に関する資料管理は必須
汎用的過ぎて何でも入るので決めや資料整理は重要。作成もその資料に慣れるのも案外大変。
属性名はこの種類、値は何パターンdate型、この属性は一つまで持てる複数持てる等。
id | attribute_name | attribute_value |
---|---|---|
001 | 武器 | 爪 |
001 | 武器 | 牙 |
001 | 武器 | 蹴り |
ろくに管理されてないと認識齟齬多発して工数かかりまくって炎上する。
④データ抽出つらいその2
抽出する属性の値の特性全部把握しないといけない。
この属性は複数可能性あるから結果配列にすべき、複数でないようにこういう条件必要とか。
その整理が案外時間かかる。
⑤データ抽出つらいその3
動作確認するための試験データ準備やパターン網羅が案外大変。
パターン在りすぎて考えるのも大変だしレビュアーもパターン足りてるのか判断もきっと難しい。
そんな感じです。