サブタイプモデルのテーブル設計

サブタイプモデルをテーブルに落とし込むには、何通りか方法があります。実装方法ごとのメリット、デメリットについて確認します。

例として、「User」のサブモデルとして「Student」と「Teacher」が存在する場合のテーブル設計について考えてみます。

447-design-subtype_table1.png

設計方法

DB設計といえば、以下の本が有名です。

SQLアンチパターン

この本の5章でサブタイプのモデリングについて取り上げられています。ここでも以下4つの方法でテーブル設計してみます。

  1. シングルテーブル継承
  2. 具象テーブル継承
  3. クラステーブル継承
  4. 半構造化データ

シングルテーブル継承

447-design-subtype_table2.png
  • 1つのテーブルにサブタイプの属性を全て詰め込みます。
  • サブタイプの識別には、user_typeを利用します。
  • サブタイプの属性が少ないときに適切です。

具象テーブル継承

447-design-subtype_table3.png
  • 「teachersテーブル」と「studentsテーブル」にそれぞれ共通属性を持たせます。
  • 共通の属性が必要になった時には、全ての具象テーブルに追加する必要があります。
  • 複数の具象テーブルをまたいで検索するには、UNIONを利用するなどの必要があり、処理が複雑になります。

クラステーブル継承

447-design-subtype_table4.png
  • 共通属性のみを持った基底テーブルに、サブタイプのテーブルが外部キーで結合します。
  • フレームワークによっては実装しずらいなどあるかもしれません。

半構造化データ

447-design-subtype_table5.png
  • サブタイプの識別には、user_typeを利用します。
  • attributesカラムの型を「TEXT」や「JSON」としておきます。
  • attributesカラムにサブタイプで必要な属性を全て格納します。
  • 「サブタイプの属性を検索などで全く利用しない」「仕様が未確定で新しい属性が頻繁に上がってくる」などのときに適してます。