SQLアンチパターンを読んで (ポリモーフィック関連について)

様々なところで名著と言われている”SQLアンチパターン”を最近読みました。この本にはデータベース設計やクエリなどでやりがちな様々な間違い(アンチパターン)が載っています。今回は私も身に覚えがあるアンチパターン:ポリモーフィック関連について紹介したいと思います。


SQLアンチパターン

ポリモーフィック関連

ポリモーフィック関連とはある一つのカラムが複数のテーブルを参照しているようなパターンです。

例えば管理ユーザテーブル(admin_users)と一般ユーザテーブル(users)によってユーザを管理している時に、それらのユーザのログをユーザログテーブル(user_logs)でまとめて記録したい場合にポリモーフィック関連を使う可能性が出てきます。

図にあるようにuser_logsテーブルはadmin_usersとusersテーブルをusers_idによって参照しており、どちらに参照するかはuser_typeによって決めるといった関連の仕方がポリモーフィック関連になります。

ポリモーフィック関連の問題点

1つのカラムで2つのテーブルに参照しているわけなので、当然外部キー宣言ができなくなります。これにより参照整合性制約(参照先に絶対レコードがあるよ!という制約)は保証できなくなってしまいます。

また、JOINを行う場合に動的にテーブルを選択することはできないので全てのテーブルを指定しなければいけなくなります。

これにより対象じゃない方のJOIN結果はNULLが入り、歪な結合結果が生まれるといった問題点もあります。

user_logs.id log user_type users_id users.id admin_users.id
123 秘密の出来事 user 11 11 NULL
245 コーヒーを飲む admin_user 22 NULL 22

解決策1 交差テーブルの作成

解決策の1つは交差テーブルを作成することです。

admin_usersテーブルとuser_logsテーブルの間に1つ交差テーブル。usersテーブルとuser_logsテーブルの間にも交差テーブルを作成することで参照整合性制約を保証することが可能となります。

解決策2 共通の親テーブルの作成

もう一つの解決方法は関連を共通の親テーブルを作成することです。

下図のように新しくparent_usersテーブルを作り、2つのユーザテーブルを束ねることで先程の2つの問題点は解消されます。

まとめ

“SQLアンチパターン”では他にも様々なアンチパターン(全25種類)がわかりやすく説明されています。今回紹介したアンチパターン:ポリモーフィック関連に関してもより詳しく書かれているので、気になった方はぜひ読んでみてください!他のアンチパターンについても別の機会に紹介できたらと思います。