sqlアンチパターンまとめ
①ジェイウォーク(信号無視)
データにカンマや区切り文字を利用してしまってる設計パターン。
問題点
長くなる・毎回更新が必要。
あと、経理だけを消したい場合に消すのがめんどかったりする。
社員cd | 所属部署 |
---|---|
1 | 営業 |
2 | 営業/経理 |
解決策
行を分けて管理する。
社員cd | 所属部署 |
---|---|
1 | 営業 |
2 | 営業 |
3 | 経理 |
ただ、分析用のデータベースなら良いかも。
集約して表示したいニーズはあるので。
②ナイーブツリー
親子関係のあるデータベースの設計
問題点
階層構造の参照が難しい。
id | 組織名 | 上位組織 |
---|---|---|
1 | 本社 | Null |
2 | 営業部 | 本社 |
3 | 経理部 | 本社 |
4 | 営業1課 | 営業部 |
解決策
id | 組織名 | 上位パス |
---|---|---|
1 | 本社 | 本社/ |
2 | 営業部 | 本社/営業部 |
3 | 経理部 | 本社/経理部 |
4 | 営業1課 | 本社/営業部/営業一課 |
ただ、参照しやすいが管理しにくい
管理の場合は上の設計で良いかと。
再起クエリを利用する手もある
③IDリクワイアド(とりあえずid)
受注idと品目idでユニークなのにidが存在する
id | 受注id | 品目cd |
---|---|---|
1 | 9001 | 11 |
2 | 9002 | 12 |
3 | 9003 | 14 |
問題点
idいらん。
データベースの構造上、整合性を保てない
id7でid6とおなじ受注idと品目idが存在した場合、整合性を保てない
解決策
受注idと品目idで主キーを構築したら整合性持てる。
代替キーを用いていい場合(上のデータ構造の場合)はあまりにも自然キー(受注idとか)が長い場合
受注id | 品目cd |
---|---|
9001 | 11 |
9002 | 12 |
9003 | 14 |
④キーレスエントリ(外部キー嫌い)
外部キーつけるかつけないか
大会テーブル | ||
---|---|---|
大会id | 主催者id | 大会名 |
主催者テーブル | ||
---|---|---|
主催者id | 主催者名 |
割と議論分かれる。
教科書的には外部キーはあった方が良い。
→db内の整合性を保つことができる。
アプリケーション側でチェックしてるなら不要
→二重チェックが必要でメンテナンスが面倒。
→データバッチで順番を意識する必要が出てくる。
⑤EAV(エンティティ・アトリビュート・バリュー)
汎用的な属性テーブルを作らない方がいいよ
品名cd | 属性名 | 属性値 |
---|---|---|
I001 | 品目名 | みかん |
I001 | 単価 | 100 |
I002 | 品目名 | レモン |
I002 | 単価 | 150 |
問題点
sqlデータ型が使えない。
not null制約など、必須設定ができない。
ただ、拡張性は高い(変更が生じた時もテーブル定義を変えなくても良い)
解決策
データ属性は横持ちしましょう。
品名cd | 品目名 | 単価 |
---|---|---|
I001 | みかん | 100 |
I002 | レモン | 150 |
未知項目はeav(上のデータ構造)でもよさそう。
⑥ポリモーフィック関連
電話とかメールの問い合わせを、一つの「問い合わせ詳細テーブル」で管理してしまう。
同じ内容だけど違う振る舞いしてしまう。
問題点
制約が使いにくい。
解決策
それぞれ別テーブルを作る。
今回だと電話のお問合せ詳細テーブル、メールのお問合せテーブルを作る。
⑦マルチカラムアトリビュート(複数列属性)
さっきのEAVと近い。
受注id | 品目名1 | 品目名2 | 品目名3 |
---|---|---|---|
1 | りんご | null | null |
2 | みかん | すいか | null |
3 | もも | メロン | イチゴ |
問題点
同じ値が複数の値に入ってしまうケースが考えられる。
正規化ができていないので管理が難しい。
(一意性の確保・更新対象列の確認)
解決策
正規化しましょう。
従属テーブルを作成
受注id | 品目名 |
---|---|
1 | りんご |
2 | みかん |
3 | もも |
⑧メタデータトリブル(メタデータ大増殖)
同じ構造のデーブルが複数存在する。
たとえば年ごとに作成
受注テーブル |
---|
受注テーブル2022 |
---|
受注テーブル2021 |
---|
問題点
汚くなる。
謎のテーブルが生まれる。
解決策
パフォーマンスを保つために過去テーブルを一つに。
受注テーブル |
---|
過去受注テーブル |
---|