質問: 外部参照制約の有無について質問させてください 以下のテーブルで | dept | user | | --- | --- | | dept_id | user_id | | - | dept_id | 親:dept、子:userの関係があるとき、 一般的にはuser.dept_idに外部参照制約を付けると思います。 例えばこのとき仕様や運用上の理由(userが先に登録されて、それに合わせてdeptを登録するパターンがある等)で user.dept_idに外部参照制約を付けないというDB設計はしてよいのでしょうか。 また、親子関係のある場合に外部参照制約を付けないときの、リスク・デメリット等を教えて頂きたいです。
回答: 外部参照制約は、値の整合性を保つという事が目的です。 オプションにもよりますが、基本的にはON UPDATE CACADE ON DELETE CACADEを設定すると思います。 参照元からレコードが削除されたら、参照先のレコードも削除されるというやつですね。 親が消えたらそれを参照している子も消えなくてはおかしいです。 それをDB側でやってもらうか、クライアント側でやるかという違いはありますが、 どう考えてもDB側でやったほうがミスがないです。 メリットは当然、整合性を保てる事です。 デメリットは、自分としては無いと考えています。 まずは基本的に設定するべきです。 逆に参照する必要があるものについて、参照制約をつけないと必ず整合性が取れないミスが生まれます。 通常において整合性取れなくていい場合ってなんなの?って感じです。 例外としては、ログをDBで保存したいケースです。 ユーザの行動履歴などをDBに保存するようなケースでは、 ユーザが退会したときに、ほんとにユーザのレコードを物理削除してしまうような運用の場合、 参照制約により関連レコードが消えてしまいます。 この場合は、ログテーブルに関しては参照制約を設定しないという事になりますが、 これはログであり、運用データではないので整合性が崩れていても問題がありません。 ログはあとで分析用に使ったりするもので、公開画面などに表示したりしないので すでに存在しないレコードの情報があってもサービス側に影響はありません。 結論ですが、自分なら基本的に参照制約を設定しますが、 ケースバイケースの事があるため、 運用的に妥当であると判断したなら設定しなくても良いと考えます。 しかしながら繰り返しになりますけども、 あとで制約を外す事もできますし、まずは設定する。 開発中あるいは運用中に問題が起きたら外す。 というのが現実的と思います。 問題が起きた=運用上、参照制約を外す必要性が生まれたという事なので。