🔑

外部キー制約はとりあえず付けるべきだと思ってた...😇

2022/11/14に公開

はじめに

以前実務で新規機能を実装するに辺り、テーブル設計から担当させて頂きました。
その際に、テーブルをリレーションさせるときは全てに「外部キー制約」を付けていたのですが、外部キー制約を付けたことで不都合が起き、上司からは以下のような場合にしか「外部キー制約」は使わないというアドバイスを頂きました。

  • PJ全体で共通して利用するような方針
  • 絶対に連動したデータを持つ必要ある場合

自分としては「外部キー制約」は付けられるなら付けた方がイイと勝手に思っていた(SQLアンチパターンの第4章:キーレスエントリを鵜呑みにしたのが原因)ので、改めて調べ直して参考になった記事を載せておこうと思います。

参考になった記事

https://zenn.dev/dowanna6/articles/2667cbb1ab7233
MySQLのマネージドサービス「PlanetScale」の「外部キー制約」に関するDiscussionsを翻訳+執筆者様のご意見が書かれている記事。こちらの記事コメントが今回自分に起きた問題であり、上司のアドバイスとほぼ同じご意見なので引用させて頂きます。

初回設計開発時は外部キーついてても良いのですが、追加開発時の外部キー制約忘れで結局意味なくなったり、その後のリファクタやサービス分割において外部キー制約があることにより開発難度が上がってしまう場合が多く、個人的には基本は外部キーつけずにアプリケーション側で担保していくのが良いと思っています。
もちろんアプリケーション側のロジックで整合性を担保しようとしてもどこかで・いつかは抜けが発生するので、それが許されないようなプロジェクトでは外部キー制約を使った方がより安全になるでしょう。多分この許される・許されないの温度感が人それぞれ、時代にもより変わり外部キー制約論争になるのかなあと思いました。
あと最近ではRDBMS以外の永続化を組み合わせることも多く、NoSQLだったりS3のようなストレージだったりまたはDBを分割したりマイクロサービス化してたり多種多様で、外部キー制約だけで整合性を担保できるシチュエーションは少なくなっているのではないかなとも思います。


https://blog.j5ik2o.me/entry/2020/06/16/105311
例を元に外部キー制約を適用すべき場合・すべきではない場合を説明されています。コメントも様々なご意見が書かれていて、そこも含めて外部キーについて考える良いキッカケになりました。


さいごに

色々と調べてみて、結局のところデータの整合性をデータベース側で担保するかアプリ側で担保するかの話になり、ケースバイケースだと思いました。何も考えずに「外部キー制約はできる限り付ける」ではなく、その場その場で最適な選択ができるようにしたいと思います。

GitHubで編集を提案

Discussion