web-dev-qa-db-ja.com

データベースで外部キーを使用する必要があるのはなぜですか?

IT分野での10年以上の経験の中で、私はどのプロジェクトでも外部キーを使用したことがなく、必要性を感じたことはありません。私は外部キーの制約があったプロのデータベースを使用していました。

現在、新しいアプリケーション/データベースを構築する立場にあり、外部キーを使用するべきかどうかを考えていますか?これはプロの製品になるでしょう。また、満足のいく回答が得られた場合は、これを既存のプロジェクトに実装することも検討します。

外部キーを使用する理由 に関するこの記事は、私の懸念に正確に対応しています。それは主な核心です

  1. 参照整合性を維持します(はい、ただしそれなしでも維持できます)
  2. より簡単な探偵の仕事(もちろん)
  3. より良いパフォーマンス(私はよくわかりません)

私の質問は、外部キーを使用するか、外部キーなしで使用できるかです。そのようなシナリオで働いた開発者の強力な長所と短所は何ですか?


例:ここで、外部キーの使用の重要な部分に、設計に追加される複雑さが追加されます。たとえば、単純な削除が機能しない場合や、知らない他のレコードが削除される場合があります。そのシナリオを考えてみましょう。

userおよびuser_commentsテーブルを含むデータベースがあります。

create table user(
user_id int not null identity,
user_name varchar(50),
...
)

create table user_comment(
comment_id int not nul identity,
user_id int,
CONSTRAINT FK_USER_USERID FOREIGN KEY (user_id)     
    REFERENCES user (user_id)
    ON DELETE CASCADE    
    ON UPDATE CASCADE 
)

ここで、ユーザーを削除すると、そのユーザーのコメントはすべて自動的に削除されます。私はその動作を変更できることを知っていますが、私の質問は、追加された複雑さで使用する価値のある外部キーですか? SE.stackexchangeユーザーの長所と短所は何ですか?ホラーストーリーを見ている可能性はありますか?誰かがそれがどのようにパフォーマンスを向上させるかについてコメントできますか?

9
Noname
  1. 参照整合性を維持します(はい、ただしそれなしでも維持できます)

あなたが技術的に正しいのは、参照整合性を自分で維持できるのであれば、制約が存在する必要はないということです。しかし、同じロジックで、家が燃えない限り、火災保険は必要ありません。病気にならない限り、健康保険は必要ありません。

技術的には正しいですが、根本的に主張できるすべてのことを完璧に行うことは、単にあなた(または他の開発者)が間違いを犯している可能性を認識できないことです。

誤って参照整合性を壊すなし外部キーは問題なく機能します。しかし、後で、データを取得したいとき、それはあなたの顔に爆発します。

  • 誰がこのデータを設定しましたか?
  • 彼らはいつそれを設定しましたか?
  • なぜ彼らはそれをこの値に設定したのですか?

これらの質問に答えることは非常に困難になります。

誤って参照整合性を壊すwith外部キーがあなたの顔に爆発するすぐに

  • 誰がこのデータを設定しましたか? あなたがやった。
  • 彼らはいつそれを設定しようとしたのですか? たった今
  • なぜ彼らはそれをこの値に設定したのですか? あなたは今それをやっているので、あなたが何をしようとしているのかを知るための論理的に最良の情報源です。

問題の原因を突き止めると、問題のトラブルシューティングが非常に簡単になります。

  1. より簡単な探偵の仕事(もちろん)

私が説明したことを意味していると思います。

  1. より良いパフォーマンス(私はよくわかりません)

誰かがパフォーマンスをどのように向上させるかについて誰かがコメントできますか?

外部キーは、少なくとも直接にはパフォーマンスを向上させません。 indexesを使用すると、パフォーマンスが向上します。 PKとFKは検索に非常に頻繁に使用されるため、自動的にインデックスが付けられ、検索最適化の主要なターゲットとなるのは、たまたまです。

ここで、ユーザーを削除すると、そのユーザーのコメントはすべて自動的に削除されます。

これは外部キーに固有のものではありません。これは、外部キーにON DELETE CASCADEを設定することに固有です。カスケード削除は便利な機能ですが、外部キーのコアユースケースではありません。中心的な使用例は、参照整合性の維持です。

私の質問は、外部キーを使用するか、それなしで生活できるかです。そのようなシナリオで働いた開発者の強力な長所と短所は何ですか。

私の質問は、追加された複雑さで使用する価値のある外部キーですか?

あなたが話している複雑さはわかりません。

既に参照整合性を処理できると主張している場合、それは私があなたのFKなしの列にFKをこっそり入れられるはずであり、私があなたの列にFKを入れていることに気付かないでしょう。 FKを使用することによる複雑さはありません。

FKの設定は簡単です。はい、明示的なSQLコマンドが必要ですが、コマンドは非常にコピー/貼り付け可能です。

CONSTRAINT unique_name FOREIGN KEY fk_column_name REFERENCES pk_table (pk_column_name)

私の怠惰な開発者は、制約に名前を付けることが本当に必要かどうか疑問に思っていますが、追加する必要がある他の情報は、2つの列間の関係を設定するために常に論理的に必要です。名前を除けば、それは可能な限り簡単です。

列にインデックスを付けることによるパフォーマンスの向上は、列にFKを付けることに固有です。 FKなしでインデックスを設定することは、FKを設定することとほぼ同じくらい複雑です。

CREATE INDEX unique_name ON fk_table_name (fk_column_name)

繰り返しになりますが、実際に外部キーを使用することで複雑さが増すことはありません。

27
Flater

ユーザーを削除する場合、なぜ孤立したコメントを保持するためにwantを使用するのでしょうか?

リレーショナルデータストアの主な利点は、このような異常が発生しないことを保証できることです。このような保証が気に入って欲しい場合は、可能な限り低いレベルで実装すること、つまり、データベースエンジンに組み込むことをお勧めします。これは、自分で行うよりも高速で安全だからです。

それらが不要な場合は、非リレーショナルデータストアを使用することをお勧めします。しかし、エンジンの1つのモデルを使用してから、その主要な利点の1つを利用することを拒否することは、奇妙に無意味に思えます。

3
Kilian Foth