私の知る限り、外部キー(FK)は、プログラマーがデータを正しい方法で操作するのを支援するために使用されます。プログラマが既にこれを正しい方法で行っているとしたら、外部キーの概念が本当に必要なのでしょうか。
外部キーの他の用途はありますか?ここで何か不足していますか?
私の知る限り、外部キー(FK)は、プログラマーがデータを正しい方法で操作するのを支援するために使用されます。プログラマが既にこれを正しい方法で行っているとしたら、外部キーの概念が本当に必要なのでしょうか。
外部キーの他の用途はありますか?ここで何か不足していますか?
回答:
外部キーは、データレベルで参照整合性を適用するのに役立ちます。また、通常はデフォルトでインデックスが作成されるため、パフォーマンスも向上します。
外部キーは、プログラマーがなどを使用してより少ないコードを書くのにも役立ちますON DELETE CASCADE
。つまり、1つのテーブルにユーザーが含まれ、別のテーブルに注文などが含まれている場合、ユーザーを削除すると、そのユーザーを指すすべての注文が自動的に削除される可能性があります。
外部キーなしでデータベースを設計することは想像できません。それらがなければ、最終的には間違いを犯し、データの整合性を破壊することになります。
彼らは必要ありません厳密にが、メリットは非常に大きくなります。
私はFogBugzがデータベースに外部キー制約を持たないことをかなり確信しています。Fog Creek Softwareチームがコードをどのように構成して、矛盾が発生しないことを保証するかについて興味があります。
FK制約のないデータベーススキーマは、シートベルトなしの運転に似ています。
ある日、あなたはそれを後悔するでしょう。設計の基礎とデータの整合性に少しの余分な時間を費やさないことは、後で頭痛を確実にする確実な方法です。
ずさんなコードをアプリケーションで受け入れますか?メンバーオブジェクトに直接アクセスし、データ構造を直接変更しました。
なぜこれが難しくなり、現代の言語では受け入れられなくなったと思いますか?
はい。
ON DELETE CASCADE
プログラマが実際にこれをすでに正しい方法で行っていると仮定します
そのような仮定をすることは、私には非常に悪い考えのようです。一般的に、ソフトウェアは驚くほどバグがあります。
そして、それが本当にポイントです。開発者は物事を正しく行うことができないため、データベースに不正なデータを入れないようにすることは良いことです。
理想的な世界では、自然結合は列名を一致させるのではなく、関係(つまり、FK制約)を使用します。これにより、FKがさらに便利になります。
個人的には、テーブル間の関係を形式化するため、外部キーを支持しています。あなたの質問がプログラマーが参照整合性に違反するデータを導入していないことを前提としていることを理解していますが、最善の意図にもかかわらず、データ参照整合性に違反する事例が多すぎます!
事前に外部キーの制約(宣言的参照整合性またはDRIとも呼ばれます)には、トリガーを使用してこれらの関係を実装するために多くの時間が費やされました。宣言的な制約によって関係を形式化できるという事実は非常に強力です。
@John-他のデータベースは外部キーのインデックスを自動的に作成しますが、SQL Serverは作成しません。SQL Serverでは、外部キー関係は制約にすぎません。外部キーのインデックスを個別に定義する必要があります(これは有益な場合があります)。
編集:追加したいのですが、IMO、ON DELETEまたはON UPDATE CASCADEをサポートするための外部キーの使用は必ずしも良いことではありません。実際には、削除のカスケードはデータの関係に基づいて慎重に検討する必要があることを発見しました。たとえば、これが問題ない自然な親子があるか、関連するテーブルがルックアップ値のセットであるかなどです。カスケード更新を使用すると、1つのテーブルの主キーを変更できるようになります。その場合、テーブルの主キーが変更されるべきではないという点で、一般的な哲学的な不一致があります。キーは本質的に一定でなければなりません。
データベースによって強制される外部キー制約について話していると思います。おそらくすでに外部キーを使用していますが、データベースについてそれを知らせていないだけです。
プログラマが既にこれを正しい方法で行っているとしたら、外部キーの概念が本当に必要なのでしょうか。
理論的には違います。ただし、バグのないソフトウェアはありません。
通常、アプリケーションコードのバグはそれほど危険ではありません。バグを特定して修正すると、アプリケーションは再びスムーズに実行されます。しかし、バグが原因で破損したデータがデータベースに入力されると、それで立ち往生してしまいます。データベース内の破損したデータから回復するのは非常に困難です。
FogBugzの微妙なバグにより、破損した外部キーがデータベースに書き込まれる可能性があるかどうかを検討してください。バグを修正し、バグ修正リリースで顧客にすばやく修正をプッシュするのは簡単かもしれません。しかし、数十のデータベースの破損したデータをどのように修正すればよいですか?正しい外部キーの整合性に関する仮定がもう成り立たないため、コードが突然壊れる可能性があります。
Webアプリケーションでは、通常、データベースと通信するプログラムは1つだけなので、バグがデータを破壊する可能性のある場所は1つだけです。エンタープライズアプリケーションでは、同じデータベースと対話する複数の独立したアプリケーションが存在する場合があります(データベースシェルで直接作業している人は言うまでもありません)。すべてのアプリケーションが、常に、そして永遠に、バグのない同じ仮定に従うことを確認する方法はありません。
制約がデータベースでエンコードされている場合、バグで発生する可能性のある最悪の事態は、SQL制約が満たされていないという醜いエラーメッセージがユーザーに表示されることです。これはたくさんです、破損したデータをエンタープライズデータベースに入れて、すべてのアプリケーションを破壊したり、あらゆる種類の誤った、または誤解を招く出力をもたらすよりも好ましい方法です。
また、外部キー制約はデフォルトでインデックスが付けられるため、パフォーマンスも向上します。外部キー制約を使用しない理由は何も考えられません。
unibrow
私が思うに、いくつかの単一の事をある時点での、有効な関係を確実にする責任があるに違いないと。
たとえば、Ruby on Railsは外部キーを使用しませんが、すべての関係自体を検証します。Ruby on Railsアプリケーションからデータベースにアクセスするだけの場合は、これで問題ありません。
ただし、データベースに書き込むクライアントが他にある場合は、外部キーがないと、独自の検証を実装する必要があります。次に、異なる可能性が最も高い検証コードのコピーが2つあります。これは、どのプログラマーもそれが主要な罪であることを伝えることができるはずです。
その時点で、外部キーは責任を1つのポイントに再び移動できるため、本当に必要です。
私の知る限り、外部キーは、プログラマーがデータを正しい方法で操作するのを助けるために使用されます。
FKにより、DBAは、プログラマーが失敗したときにユーザーの手ごたえからデータの整合性を保護し、場合によってはプログラマーの手ごたえから保護することができます。
プログラマが既にこれを正しい方法で行っているとしたら、外部キーの概念が本当に必要なのでしょうか。
プログラマーは人間であり、間違いです。FKは宣言的であるため、失敗することが難しくなります。
外部キーの他の用途はありますか?ここで何か不足していますか?
これが作成された理由ではありませんが、FKは、作図ツールとクエリビルダーに強力で信頼性の高いヒントを提供します。これは、強力で信頼性の高いヒントを切実に必要とするエンドユーザーに渡されます。
アプリケーションがデータベース内のデータを操作できる唯一の方法ではないため、これらは重要です。アプリケーションは参照整合性を必要に応じて正直に処理できますが、必要なことは、データベースレベルで挿入、削除、または更新コマンドを実行するための適切な権限を持つ1つのbozoだけであり、すべてのアプリケーションの参照整合性の適用はバイパスされます。FK制約をデータベースレベルで配置すると、このbozoがコマンドを発行する前にFK制約を無効にすることを選択しないと、FK制約により、挿入/更新/削除ステートメントが失敗し、参照整合性違反が発生します。
コスト/メリットの観点から考えます... MySQLでは、制約の追加はDDLの 1行の追加ですです。それはほんの一握りのキーワードと数秒の思考です。それは私の意見では唯一の「コスト」です...
ツールは外部キーを愛します。外部キーは、ビジネスロジックまたは機能に影響を与えないために気付かれずに蓄積される不良データ(つまり、孤立した行)を防ぎます。また、スキーマに不慣れな開発者が、関係が欠落していることに気付かずに作業のチャンク全体を実装することもできません。おそらく、現在のアプリケーションの範囲内ではすべてが素晴らしいですが、何かを見落とし、いつか予期しない何かが追加された場合(空想的なレポートと考えてください)、最初から蓄積されている不良データを手動でクリーンアップする必要がある場合があります。データベースがチェックを強制しないスキーマの。
物事をまとめるときにすでに頭の中にあるものを成文化するのにかかる少しの時間は、あなたや他の誰かが、数ヶ月または数年の悲しみをたくさん救うことができます。
質問:
外部キーの他の用途はありますか?ここで何か不足していますか?
少しロードされています。「外部キー」の代わりにコメント、インデント、または変数名を挿入します...問題の問題を完全に理解している場合は、「使用しない」ことになります。
エントロピーの削減。データベースで無秩序なシナリオが発生する可能性を減らします。すべての可能性を考慮しているので、私たちは苦労しています。したがって、私の意見では、エントロピーの低減は、あらゆるシステムのメンテナンスの鍵となります。
たとえば、仮定を立てるとき:各注文には、何かによって仮定が強制されるべきであるという顧客がいます。データベースでは、「何か」は外部キーです。
これは開発速度のトレードオフの価値があると思います。確かに、それらをオフにしておくとより速くコードを作成できます。これがおそらく一部の人々がそれらを使用しない理由です。個人的には、NHibernateといくつかの操作を実行すると怒るいくつかの外部キー制約で数時間を殺しました。しかし、私は問題が何であるかを知っているので、それほど問題ではありません。私は通常のツールを使用しており、これを回避するのに役立つリソースがあります。
代替策は、外部キーが設定されておらず、データが不整合になるバグがシステムに侵入することを許可することです(十分な時間が与えられれば、システムに侵入します)。次に、異常なバグレポートを取得し、調査して「OH」にします。データベースが台無しになっています。それを修正するには、どれくらい時間がかかりますか?
現在、外部キーは使用していません。そして、大部分は後悔していません。
とはいえ、いくつかの理由により、近い将来、それらの使用がさらに増えると思われます。両方とも、同様の理由からです。
作図。正しく使用されている外部キー関係がある場合は、データベースの図を作成する方がはるかに簡単です。
ツールのサポート。適切な外部キー関係がある場合は、LINQ to SQLに使用できるVisual Studio 2008を使用してデータモデルを構築する方がはるかに簡単です。
ですから、私のポイントは、多くの手動のSQL作業(クエリの構築、クエリの実行、何とか)を実行している場合、外部キーは必ずしも必須ではないことを発見したということです。ただし、ツールの使用を開始すると、ツールはより便利になります。
外部キー制約(および実際の制約一般)の最も良い点は、クエリを作成するときにそれらに依存できることです。「true」を保持するデータモデルに依存できない場合、多くのクエリはさらに複雑になる可能性があります。
コードでは、通常、どこかで例外がスローされますが、SQLでは、通常、「間違った」答えが返されます。
理論的には、SQL Serverはクエリプランの一部として制約を使用できますが、パーティション分割のチェック制約を除いて、実際にそれを目にしたことはありません。
外部キーは、私が取り組んでいるプロジェクト(ビジネスアプリケーションおよびソーシャルネットワーキングウェブサイト)で宣言されていなかった(FOREIGN KEY REFERENCESテーブル(列))。
しかし、常に外部キーである列の命名規則のようなものがありました。
それはデータベースの正規化のようなものです-あなたはあなたが何をしているか、そしてその結果(主にパフォーマンス)が何であるかを知る必要があります。
外部キーの利点(データ整合性、外部キーカラムのインデックス、データベーススキーマを認識するツール)は知っていますが、一般的なルールとして外部キーを使用することも怖いです。
また、さまざまなデータベースエンジンが異なる方法で外部キーを提供する可能性があり、移行中に微妙なバグにつながる可能性があります。
ON DELETE CASCADEを使用して、削除されたクライアントのすべての注文と請求書を削除することは、見栄えは良いが設計が間違っているデータベーススキーマの完璧な例です。
はい。ON DELETE [RESTRICT | CASCADE]は、開発者がデータを取り残さないようにし、データをクリーンに保ちます。私は最近、外部キーなどのデータベースの制約に重点を置かなかったRails開発者のチームに参加しました。
幸いなことに、私はこれらを見つけました:http : //www.redhillonrails.org/foreign_key_associations.html-Ruby on RailsプラグインのRedHillは、設定スタイルの規約を使用して外部キーを生成します。product_idを使用した移行では、productsテーブルのidへの外部キーが作成されます。
トランザクションにラップされた移行を含む、RedHillの他の優れたプラグインをチェックしてください。