以下の内容はhttps://rukiadia.hatenablog.jp/entry/2026/02/05/000608より取得しました。


外部キーNightに参加してきた

https://connpass.com/event/380098/

外部キー制約に興味があったので参加してきた。

以前は「外部キー制約はとりあえず作っておくもの」程度の認識でいたが、昨年の秋〜冬に外部キー制約がほぼ存在しないテーブル群の手入れをしていた時に「外部キー制約を作らない方が良い場面はあるのか?」と考えるようになった。これがイベントに参加しようと思ったきっかけ。

参加してどうだったか?

外部キーは必要だなと再認識した。

不要な場面が存在しないとまでは言わないが、データの不整合が発生するリスクを呑みで外部キーを設けない選択は今のところ取り得ない。少なくとも今日時点ではそう。

結論に至った経緯

昨年、外部キー制約がほぼ存在しないテーブル群の手入れをしていたことは冒頭で述べた。具体的には製品の利用を解約した顧客の利用データを削除する仕組みを作っていて、これがなかなかに大変だった。オープンな場で語っても問題ない形で詳細を書いておく。

外部キー制約が無いテーブル

自分が関わっている製品はとあるSaaSに依存していて、SaaSの方に残るログを自社側のデータベースに残している。なお、ログは顧客の解約に伴って削除する必要がある。

テーブルA(コアデータ)とテーブルB(関連データ)の1:Nの関係性

実際の構成図は載せられないので、詳細をぼかしつつ構成を単純にしたイメージを載せた。製品利用に伴って生成される利用データのコア部分がテーブルA、コア部分に1:Nの関係性で紐づく関連データをテーブルBに永続化している。core_data_idによる外部キー制約がないことが影響して、以下のような問題が起きた。

  • 外部キー制約がないので、テーブルAに関連するテーブルBのデータを厳密に特定できない。
  • テーブルAのid、テーブルBのcore_data_idは等しくなるようにアプリケーションで実装がされているが、データベースによる制約が無いのでデータの完全性は失われている。実際、親データとなるレコードが存在しないテーブルBのレコードが存在していた。さらに補足すると、依存先のSaaSのログは一定期間で消える仕様なので、データの復元は不可能だった。

「外部キー制約があれば、こんなことには・・」という場面が実際にあったという話である。幸いなことに、テーブルBに顧客IDのカラムがあったので消すべきデータの特定が可能なのが救いだが、顧客IDのカラムは「Row Level Securityを将来的に設けるため」に作ったものだったので救われたのは完全に偶然だった。

まとめ

こうした経緯があり、「データの整合性が第一」という思考に則って外部キーは作る派に一票を投じておく。ただ、外部キー制約起因のテーブルロックによるパフォーマンス影響は確かに存在するので、将来の大きな問題にならないように考慮はしておくべきは思うので、現状のデータベース構成に改善点がないかどうかを改めて見直すことにする。

 




以上の内容はhttps://rukiadia.hatenablog.jp/entry/2026/02/05/000608より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14