SQLアンチパターン-6章 ポリモーフィック関連-まとめ
複数のモデルにまたがって存在しているモデルの扱い
1対多、多対多の関係性のあるモデルについて考えます。
本(book)モデルと
コメント(comment)モデルがあったとしましょう。
- 本に対してコメントをつけられる事ができます。
- 本に対してコメントは複数つける事ができます。
ここで、本の執筆者である
著者(author)モデルを考えてみましょう。
- 著者に対してコメントをつけられる事ができます。
- 著者に対してコメントは複数つける事ができます。
このとき、コメントモデルには外部キーが2つ出現しています。
book_id
と author_id
です。
この2つのキーが被ってしまう恐れがあるので
単純にテーブル結合をしてデータを取り出すことはできなくなります。
ポリモーフィック関連
上記のパターンになったときに、思いつかれる解決策があります。
それがポリモーフィック関連と言います。
単純に book_id
と author_id
を扱う場合、
コメントテーブルに列をそれぞれ作成すれば良いです。
しかし、他にもコメントがつけられるようなモデルが新たに作成されたらどうなるでしょうか。
例えば本だけでなく、映画、テレビ、などなど・・・。
それぞれ movie_id
や tv_id
など、何かしらNULLの値が入ってしまう列を作ってしまうことになります。
それでは、コメントをつけるモデルのidと、その種類分けを定義した列、
comment_type
と commented_id
を追加したらどうなるでしょうか。
ある行では
comment_type = book
commented_id = 2
また、ある行では
comment_type = author
commented_id = 3
というように、表す事ができるようになります。
デメリット
しかしポリモーフィック関連を使って設計すると
外部キーとして扱っている commented_id
が、実際には外部キー宣言をせずして扱うことになってしまいます。外部キーは1つのテーブルにしか紐づける事ができないからです。
そのため、その外部キーがあるテーブルと紐づいたときに、値が存在しているのかを保証するための参照整合性制約を設ける事ができなくなります。
また、コメントテーブルのデータを取得する場合、
外部結合で複数のモデルを結合し、結合する必要があります。
ポリモーフィック関連を使うと、DBのでデータ制約を利用する事ができなくなるので
アプリケーション側で調整する必要があります。
Railsはこの問題に対応している
フレームワークによってはこの問題に対応しているものもあります。
例えばRailsでは、polymorphic属性を宣言する事で、1つのモデルを複数のモデルに紐づけて外部キーを設定する事ができます。
ポリモーフィック関連を使う場面
外部キーのように紐づけたいモデルが、複数存在し、かつ、どのようなモデルが現れうるのか、将来的に不透明であるという確度が高いときには利用せざるを得ないかもしれません。
ポリモーフィック関連の代替策
交差テーブルを作成する
最初の例を元に説明すると
books_comments
テーブルと
authors_comments
テーブルを作成する方法です。
交差テーブルが存在する事で、どのモデルを示すかを表していた comment_type
を利用する必要が無くなります。
注意点としては、UNIQE制約を利用しないと、自然と多対多の関連づけが作成されてしまう事です。
また、両方の交差テーブルに同じ comment_id
が存在しうるので、
アプリケーション側で対応する必要もあります。
共通の親テーブルを作成する
book
, author
, comment
の全ての親となる reputation
モデルを作成したとします。
book
, author
, comment
の全てが外部キーとしてreputation_id
という擬似キーを持たせる事で、コメントモデルを元に同じreputation_id
に紐づいたbook
、author
モデルのデータを引っ張る事が可能になります。逆も然りで、book
から同じreputation_id
に紐づいたcomment
データを引っ張る事もできるようになります。
交差テーブルを作らなくても、擬似キーだけでデータの整合性制約を利用した設計をする事が可能になります。
Author And Source
この問題について(SQLアンチパターン-6章 ポリモーフィック関連-まとめ), 我々は、より多くの情報をここで見つけました https://qiita.com/aaaaanochira/items/cd374c05ce5e1dcf0b71著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .