コンテンツにスキップ

設計:SQLアンチパターン

SQLに関するアンチパターンをまとめたもの。 自分が関わったことのある設計について記載。

1. Jaywalking(信号無視)

開発者はよく、「多対多」の関連を表現する交差テーブルの作成を避けるために、カンマ区切りのリストを使います。 私はこのアンチパターンをJaywalkingと名づけました。どちらも、"intersection"を避けようとする行為だからです。

カンマ区切りの値を入れること。半構造データみたいになる。

book_id book_name book_tags
1 Spring MVC Java,Spring,SpringMVC
2 はじめてのScala Scala,入門

解決策:交差テーブルを作成

book_id book_name
1 Spring MVC
2 はじめてのScala
book_tag_id book_tag_name
1 Java
2 Spring
3 SpringMVC
4 Scala
5 入門
book_id book_tag_id
1 1
1 2
2 3
2 4
2 5

5. EAV (Entity Attribute Value)

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

名称 役割
Entity 親テーブルに対応した外部キーを格納
Attribute カラム名に相当する属性名を指定
Value 属性の値
book_id
1
book_id attribute value
1 name 本名
1 release_date 2020/9/24
1 price 5
  • メリット
    • テーブルの列数を削減できる
    • 新規の属性を追加する際に列数を増加しなくて良い
    • 属性が存在しない列にNULLが入りNULLだらけのテーブルにならない
    • データベースの構造は単純になる
  • デメリット
    • データの取得が冗長化する
    • 特定の属性にNOT NULL制約を設定できない
    • データ型を使用できない
    • 外部制約キーを使用できない
    • 動的に属性名が増えるため整合性が担保しづらい

解決策:サブタイプでのモデリングを行う

大きく分けて4種類の継承方法がある。

  • シングルテーブル継承
  • 具象テーブル継承
  • クラステーブル継承
  • 半構造化データ

シングルテーブル継承で作成する場合

book_id book_name book_release_date book_price
1 本名 2020/9/24 5

7. Multi Column Attribute

複数列属性を持つようなアンチデザインパターン。Jaywalkingに似ている。

  • 属性の検索が複雑になる
  • 属性の追加・削除がしにくい
  • 属性の一意性を保証できない
  • 属性列の増加が起こりうる
book_id book_name book_tag_1 book_tag_2 book_tag_3 book_tag_4
1 Spring MVC Java Spring SpringMVC NULL
2 はじめてのScala Scala 入門 NULL NULL

解決策:交差テーブルを作成

同じ意味を持つ値は、1つの列に格納して別テーブルとし、1:nやn:nのリレーションを作成すれば良い。

book_id book_name
1 Spring MVC
2 はじめてのScala
book_tag_id book_tag_name
1 Java
2 Spring
3 SpringMVC
4 Scala
5 入門
book_id book_tag_id
1 1
1 2
2 3
2 4
2 5

参考