今回は、あまり見かけないようで意外と必要になる「複数のテーブルに対して多対一で紐づくテーブル」の設計について、4つのアプローチをご紹介します。
どのようなケース?
あるテーブルが複数のテーブルのいずれかに対して、自身が多、紐付き先が一で関連する場合のテーブル設計です。
例えば、「記事」と「画像」を投稿できるようなSNSを想定します。
この時、閲覧者が投稿された「記事」と「画像」のどちらにも「コメント」をつけることができる機能があったとします。
このような場合に、どのようなテーブルの設計方法があるのか、以下から説明していきます。
1.ポリモーフィック関連
SQLアンチパターンにも登場するこの設計方法。「どのテーブルのどのレコード(id)に紐づくのか」という情報をテーブルに持たせてしまうという方法です。具体的には以下のような設計になります。
comments.target_tableに関連する対象のテーブル名を、comments.target_idに関連する対象レコードのIDを格納します。
例えば、以下のようなレコードが入ります。
シンプルな設計方法ですが、SQLアンチパターンでも取り上げられている通り、あまり良い設計ではないと言えます。
具体的には、外部キーの設定ができないため、commentsが紐づく対象について保証することができないというデメリットがあります。
そのため、整合性の保持が完全にアプリケーション側に依存する事になってしまいます。
また、target_idが示す先のテーブルがレコードによって変化してしまうというのは、気持ち悪く感じてしまう人もいるのではないでしょうか?
しかしながら、Ruby On RailsのActiveRecordなどの一部のORマッパーはこのポリモーフィック関連をサポートしているため、そのようなORマッパーを使用する際にはこの方法を使用することをお勧めします。
2.複数の関連テーブル
紐づく対象のテーブルごとに関連テーブルを作成する方法です。以下のような設計になります。
個人的にはあまり無理のない分かりやすい設計ではないかと思います。
1つのコメントが記事と画像の両方に対して紐付かないよう制約をかける事ができない、というデメリットはあります。しかし、対応しているORマッパーを使用しなかった場合の「1.ポリモーフィック関連」の方法と比較すると、データの整合性の担保という観点ではこちらの方法のほうが良い設計になります。
この設計の場合は以下のようなレコードが入ります。
3.親テーブルの作成
親テーブル(基底クラス)が抜けているために設計がうまくできない、というケースも要件によってはあり得ます。そのような場合は、以下のような設計が考えられます。
記事(articles)と画像(photos)の親として投稿(posts)テーブルを作成します。
この設計方法でも、1つのコメントが記事と画像の両方に紐づかないように制約をかけることができません。厳密にいうと、1つのコメントは1つの投稿に対してのみ紐づきますが、1つの投稿に対して記事と画像の両方を紐付けることが出来てしまいます。
しかし、今回の例に挙げたような「記事や画像の投稿に対してコメントをつける」というケースであれば、背景となるサービスの仕様やプロジェクトの状況などにもよりますが、綺麗な設計と言えるのではないでしょうか?
紐づく対象のテーブルが頻繁に増加するような場合には特に考慮したい設計です。
4.テーブルの分割
そもそも、本当にcommentsを一つのテーブルに保存する必要性があるのか?というアプローチです。
要件として、commentsを一つのテーブルにまとめておいたほうが今後都合がよい、という場合もあります。
しかし、もしもそのような状況ではないのなら、最初からテーブル自体を分割しておくという選択肢も十分にあり得るのではないでしょうか?
現状で紐づく対象のテーブルが少なく、今後も増える可能性が低い場合には考慮したい設計です。
どの方法を用いて設計を行うべきか
サービスの仕様やプロジェクトの今後の見通しなど様々な要因が絡んでくるため、一概に「この方法が最強!」とは言えません。
結局のところはすべてケースバイケースとなってしまいますが、どの方法を用いて設計を行うかの判断基準を簡単にまとめます。
いかがでしたでしょうか?
ちなみに私は「3.親テーブルの作成」や「2.複数の関連テーブル」のアプローチが好みですが、アプリケーション側の実装をする際にjoinするテーブルが増えることを考えると、少し気が滅入ってしまいます。
以上、拙い解説ではありますが、少しでも設計の役に立てば幸いです。
また、弊社では開発からサービスの運用まで、幅広くご支援させていただいております。
是非一度ください。
また、詳しいサービス内容に関しては、当社ホームページをご参照ください。
About The Author
スパイスファクトリー公式
スパイスファクトリーは世界がより良い⽅向に向かうよう、変化を加速させる “触媒”(スパイス)としての役割を全うすることをミッションとしたDXエージェンシーです。最新テクノロジー、UIUX、アート、マーケティングなどの技術・メソッドを⽤いて、モノゴトを素早く、美しく、本質的に再定義し、幅広いクライアントのデジタルトランスフォーメーションを⽀援しています。