私の知る限り、外部キー (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 つのテーブルの主キーを変更できるようになります。その場合、テーブルの主キーが変更されるべきではないという点で、私は一般的な哲学的意見の相違があります。キーは本質的に定数でなければなりません。
外部キーがなければ、異なるテーブルの 2 つのレコードが関連しているとどのように判断できるでしょうか?
あなたが言及しているのは参照整合性であり、既存の親レコードなどがなければ子レコードを作成することはできません。これらはしばしば外部キー制約として知られていますが、外部キーの存在と混同しないでください最初の場所。
外部キーを持たないことには利点がありますか? 質の悪いデータベースを使用していない限り、FK のセットアップはそれほど難しくありません。では、なぜそれらを避ける方針を持っているのでしょうか? 列が別の列を参照するという命名規則を持つことと、データベースが実際にその関係を検証していることを知ることは別のことです。
FK は非常に重要であり、eBay でない限り、常にスキーマに存在する必要があります。
データベースによって強制される外部キー制約について話していると思います。あなたはおそらくすでに外部キーを使用していますが、それについてデータベースに伝えていないだけです。
プログラマーがすでに正しい方法でこれを実際に行っているとしたら、外部キーの概念は本当に必要なのでしょうか?
理論的には、いいえ。ただし、バグのないソフトウェアはありません。
通常、アプリケーション コードのバグはそれほど危険ではありません。バグを特定して修正すると、アプリケーションは再びスムーズに実行されます。しかし、バグが原因でデータベースに不正なデータが入力される場合は、そのバグに悩まされていることになります。データベース内の破損したデータから回復することは非常に困難です。
FogBugzの微妙なバグにより、破損した外部キーがデータベースに書き込まれる可能性があるかどうかを検討してください。バグを修正し、バグ修正リリースで修正を顧客にすばやくプッシュするのは簡単かもしれません。しかし、何十ものデータベースの破損したデータをどのように修正すればよいのでしょうか? 外部キーの整合性に関する仮定が成り立たなくなるため、正しいコードが突然壊れる可能性があります。
Web アプリケーションでは、通常、データベースと対話するプログラムは 1 つしかないため、バグによってデータが破損する可能性がある場所は 1 つだけです。エンタープライズ アプリケーションでは、複数の独立したアプリケーションが同じデータベースと通信する場合があります (データベース シェルを直接操作する人々は言うまでもありません)。すべてのアプリケーションが、常に、そして永久に、バグなしで同じ仮定に従うことを確認する方法はありません。
制約がデータベースにエンコードされている場合、バグで起こりうる最悪の事態は、満たされていないSQL制約に関する醜いエラー メッセージがユーザーに表示されることです。これは、エンタープライズ データベースに破損したデータを入れるよりもはるかに望ましい方法です。そうすると、すべてのアプリケーションが壊れたり、あらゆる種類の間違った出力や誤解を招く出力が発生したりするだけです。
ああ、外部キー制約もパフォーマンスを向上させます。これは、既定でインデックスが作成されるためです。外部キー制約を使用しない理由は考えられません。
有効な関係を確保するためには、ある時点で何かが責任を負わなければならないと思います。
たとえば、Ruby on Railsは外部キーを使用しませんが、すべての関係自体を検証します。その Ruby on Rails アプリケーションからのみデータベースにアクセスする場合は、これで問題ありません。
ただし、データベースに書き込みを行っている他のクライアントがいる場合は、外部キーがなければ独自の検証を実装する必要があります。次に、おそらく異なる検証コードの 2 つのコピーを取得します。これは、どのプログラマーも大罪であると判断できるはずです。
その時点で、責任を再び単一のポイントに移動できるようにするため、外部キーが本当に必要です。
外部キーを使用すると、データベースを見たことがない人でも、テーブル間の関係を判断できます。
今はすべてうまくいっているかもしれませんが、プログラマーが辞めて、誰かが引き継がなければならなくなったらどうなるか考えてみてください。
外部キーを使用すると、何千行ものコードを調べなくてもデータベース構造を理解できます。
私の知る限り、外部キーは、プログラマーが正しい方法でデータを操作できるようにするために使用されます。
FK を使用すると、DBA は、プログラマーが失敗した場合にユーザーの手探りからデータの整合性を保護し、場合によってはプログラマーの手探りから保護することができます。
プログラマーがすでに正しい方法でこれを実際に行っているとしたら、外部キーの概念は本当に必要なのでしょうか?
プログラマーは致命的で間違いやすい。FK は宣言型であるため、失敗しにくくなっています。
外部キーの他の用途はありますか? ここで何か不足していますか?
これが作成された理由ではありませんが、FK は、作図ツールとクエリ ビルダーに強力で信頼性の高いヒントを提供します。これは、強力で信頼できるヒントを必死に必要としているエンド ユーザーに渡されます。
シートベルトが厳密に必要ではないのと同じように、それらは厳密には必要ではありません。しかし、データベースを台無しにするばかげたことをすることから本当にあなたを救うことができます.
アプリケーションを壊した削除を再構築するよりも、FK 制約エラーをデバッグする方がはるかに優れています。
アプリケーションがデータベースでデータを操作できる唯一の方法ではないため、これらは重要です。アプリケーションは参照整合性を思いのままに処理することができますが、データベース レベルで挿入、削除、または更新コマンドを発行するための適切な権限を持つ 1 つのボゾだけが必要であり、アプリケーションの参照整合性の適用はすべてバイパスされます。データベース レベルで FK 制約を設定するということは、このボゾがコマンドを発行する前に FK 制約を無効にすることを選択しない限り、FK 制約によって不適切な挿入/更新/削除ステートメントが参照整合性違反で失敗することを意味します。
コスト/メリットの観点から考えます... MySQLでは、制約を追加することはDDLの1行追加です。それはほんの一握りのキーワードと数秒の思考です。それが私の意見では唯一の「コスト」です...
ツールは外部キーが大好きです。外部キーは、ビジネスロジックや機能に影響を与えない可能性のある不正なデータ(つまり、孤立した行)を防ぎ、そのために気付かれずに蓄積されます。また、スキーマに慣れていない開発者が、関係が失われていることに気付かずに、作業のチャンク全体を実装することを防ぎます。おそらく、現在のアプリケーションの範囲内ですべてが素晴らしいですが、何かを見逃し、いつか予期しないものが追加された場合(派手なレポートを考えてください)、最初から蓄積されている不良データを手動でクリーンアップする必要がある場所にいる可能性がありますデータベース強制チェックなしのスキーマの。
あなたが物事をまとめるときにあなたの頭の中にすでにあるものを成文化するのにかかる少しの時間は、あなたや他の誰かを数ヶ月または数年先の悲しみの束を救うことができます。
質問:
外部キーの他の用途はありますか?ここで何かが足りませんか?
少しロードされています。「外部キー」の代わりにコメント、インデント、または変数の名前を挿入します...問題のことをすでに完全に理解している場合、それは「役に立たない」です。
エントロピーの削減。データベースでカオスシナリオが発生する可能性を減らします。すべての可能性を検討しているので苦労しているので、私の意見では、エントロピーの削減はあらゆるシステムの維持の鍵です。
たとえば、仮定を立てる場合、各注文には、仮定を何かによって強制する必要があるという顧客がいます。データベースでは、「何か」は外部キーです。
これは、開発速度のトレードオフの価値があると思います。確かに、それらをオフにするとより迅速にコーディングできます。これが、おそらく一部の人々がそれらを使用しない理由です。個人的には、NHibernateと、操作を実行すると怒る外部キー制約で何時間も殺しました。しかし、私は問題が何であるかを知っているので、それはそれほど問題ではありません。私は通常のツールを使用しており、これを回避するのに役立つリソースがあります。
別の方法は、外部キーが設定されておらず、データに一貫性がなくなる場合に、バグがシステムに忍び寄ることを許可することです(そして、十分な時間が与えられれば、そうなります)。次に、異常なバグレポートを取得し、調査して「OH」します。データベースがねじ込まれています。さて、それを修正するのにどれくらい時間がかかりますか?
外部キー制約(および実際には一般的な制約)の最も優れている点は、クエリを作成するときにそれらに依存できることです。「true」を保持するデータモデルに依存できない場合、多くのクエリがさらに複雑になる可能性があります。
コードでは、通常、どこかで例外がスローされますが、SQLでは、通常、「間違った」答えが返されます。
理論的には、SQL Serverはクエリプランの一部として制約を使用できますが、パーティション化のチェック制約を除いて、実際にそれを目撃したとは言えません。
外部キーは、次のような制約と見なすことができます。
現在、外部キーは使用していません。そして、ほとんどの場合、私たちはそれを後悔していません.
とは言っても、いくつかの理由で、近い将来、それらをより多く使用し始める可能性があります。どちらも同様の理由によるものです。
作図。外部キー関係が正しく使用されている場合、データベースの図を作成するのは非常に簡単です。
ツールのサポート。適切な外部キー関係があれば、Visual Studio 2008を使用してLINQ to SQLに使用できるデータ モデルを構築する方がはるかに簡単です。
つまり、私の言いたいことは、多くの手作業の SQL 作業 (クエリの構築、クエリの実行、ブラブラブラ) を行っている場合、外部キーは必ずしも必須ではないことがわかったということです。ただし、ツールを使い始めると、ツールはより便利になります。
私が携わったプロジェクト (ビジネス アプリケーションやソーシャル ネットワーキング Web サイト) では、外部キーが明示的に (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の他の優れたプラグインをチェックしてください。