web-dev-qa-db-ja.com

外部キーを使用する必要がありますか?

重複の可能性:
外部キーの何が問題になっていますか?

私は約4GBのデータの大規模なデータベースでMSSQLServerを使用しています。

外部キーを使用する理由をウェブで検索します。今では、テーブルの結合に使用されるキーのみにインデックスを付けました。パフォーマンスはすべて良好で、データの整合性は問題ありません。

外部キーを使用する必要がありますか?外部キーでさらにパフォーマンスが向上しますか?

23
Tuan

外部キーは実際にはパフォーマンスを向上させません。実際、制約が確実に守られるように、すべての書き込み操作でわずかなパフォーマンスペナルティが発生します。

これらを使用する理由は、破壊的な書き込み操作を防ぐためです。それらがない場合、バグのあるコード、または不正なSQLステートメントにより、そこにあると予想される行が削除される可能性があります。

14
Dana the Sane

今日は誠実さは問題ではないかもしれませんが、それが明日または2週間後に問題となる正確な態度です。

13
Tom H

外部キーは、主にデータベースの整合性を強化するためのツールであり、実行速度とは関係ありません。

インデックスの設計をすでに最適化している場合は、少なくともこれらのインデックスが、少なくとも一意でないインデックスとしてインストールされている可能性があります。したがって、外部キーをインストールしただけではパフォーマンスが変わるとは思いません(whicbは必ずしもインデックスを必要としません)。

ただし、この概念をまだ明確にしていない場合は、設計の最適化についてのあなたの自己満足に少し疑いを持っています。

整合性を強化するために外部キーが何をするのかを理解することを目的として、外部キーのドキュメントを読んでください(いずれにしても知っておく価値があります)。

6
dkretz

SquareCogが以前にリンクした以前の質問で言及されなかったこと-はい、外部キー制約は、データのクリーンアップ、バッチ更新、テストデータの生成、または通常の一連の処理をバイパスするあらゆるタイプの操作を実行するときに苦痛になる可能性があります。ただし、このようなことを行う前に、いつでも外部キー制約を削除して、後で再作成することができます(データベースオブジェクトが適切にスクリプト化されている場合、これは余分な作業ではありません)。

以前は怠惰でしたが、外部キーの制約に依存するようになりました。データベース間の関係のように、それらを使用できない状況がまだあります。

4
cdonner

MySQLでは、SET FOREIGN_KEY_CHECKS=0を使用して外部キーを無効にできます。

4
Mr Bumbles

外部キーがシステムにもたらす機能/制約が1つありますが、これまでは言及されていません。それがコミット/トランザクションロジックです(とにかくそれを私は呼んでいます)。外部キーを有効にすると、影響を受けるすべてのテーブルの更新のすべての行が、コミットが機能するために存在する必要があります(外部キー制約に違反しているというSQLエラーをスローしないでください)。

コミット/トランザクションを使用して機能し、「速くて緩い」コードの本体がある場合。次に、スキーマ内のFKで動作させるために、いくつかの修正を行うことができます。

また、少なくともOracleでは、制約を無効にすることができます(ドロップ/削除だけではありません)。そのため、簡単にオン/オフを切り替えることができます。制約のオーバーヘッドなしでいくつかの一括操作を実行する場合、または制約に失敗する中間状態を持つデータに対していくつかの「手術」を実行する場合に便利です。

4
Aussie Craig

外部キーは、データベースにカスケードドロップを実行させることができるため、データベースをクリーンに保つのにも役立ちます。

2
Milhous

外部キーを使用すると、データの整合性が向上し、パフォーマンスが向上します。削除、挿入、更新の際に速度が多少低下します。
私の最後の会社では、BLの変更が簡単になるため、BLの整合性/接続を維持することにしました(数億のレコードを考えてください)。あなたが小さなアプリを持っているなら、私はデータレイヤー(db)でそれをしない理由はありません