269

Joel Spolskyがポッドキャスト 014で、外部キーをほとんど使用したことがないと述べたのを聞いたのを覚えています (私の記憶が正しければ)。ただし、データベース全体での重複とその後のデータ整合性の問題を回避するために、それらは非常に重要に思えます。

人々はその理由について確固たる理由を持っていますか (Stack Overflow の原則に沿った議論を避けるため)?

編集: 「外部キーを作成する理由がまだないので、これが実際に外部キーを設定する最初の理由かもしれません。」

4

38 に答える 38

372

外部キーを使用する理由:

  • 孤立した行は取得されません
  • 「カスケードの削除時」の動作が良くなり、テーブルが自動的にクリーンアップされます。
  • データベース内のテーブル間の関係を知ることは、オプティマイザーが結合カーディナリティのより良い見積もりを取得できるため、最も効率的な実行のためにクエリを計画するのに役立ちます。
  • FKは、データベースで収集するのに最も重要な統計についてかなり大きなヒントを提供します。これにより、パフォーマンスが向上します。
  • それらはあらゆる種類の自動生成されたサポートを可能にします-ORMはそれ自体を生成することができ、視覚化ツールはあなたのために素晴らしいスキーマレイアウトを作成することができます。
  • プロジェクトに不慣れな人は、暗黙の関係が明示的に文書化されているため、物事の流れにすばやく入ることができます

外部キーを使用しない理由:

  • FKの整合性をチェックする必要があるため、すべてのCRUD操作でDBを余分に機能させることになります。解約率が高い場合、これは大きなコストになる可能性があります
  • 関係を強制することにより、FKは、追加/削除する必要のある順序を指定します。これにより、DBが必要な処理を拒否する可能性があります。(そのような場合、あなたがやろうとしているのは孤立した行を作成することですが、それは通常は良いことではありません)。これは、大規模なバッチ更新を行っているときに特に苦痛であり、2番目のテーブルが一貫した状態を作成して、あるテーブルを次々にロードします(ただし、2番目のロードが失敗して、データベースに一貫性がなくなりましたか?)
  • データがダーティになることを事前に知っていて、それを受け入れ、DBに受け入れてもらいたい場合があります。
  • あなたはただ怠惰です:-)

ほとんどの確立されたデータベースは、強制されない外部キーを指定する方法を提供し、単なるメタデータであると思います(私にはわかりません!)。非施行はFKを使用しないすべての理由を一掃するため、2番目のセクションの理由のいずれかが当てはまる場合は、おそらくそのルートに進む必要があります。

于 2008-09-17T13:46:37.390 に答える
83

これは育て方の問題です。教育または職業上のキャリアのどこかで、データベースの提供と管理に時間を費やした場合 (またはデータベースを使用した才能のある人々と緊密に協力した場合)、エンティティと関係の基本的な信条は、あなたの思考プロセスに深く根付いています。これらの基礎の中には、データベースでキーを指定する方法/時期/理由 (プライマリ、外部、およびおそらく代替) があります。それは第二の性質です。

ただし、過去に RDBMS 関連の取り組みでこれほど徹底した、または前向きな経験をしたことがない場合は、そのような情報にさらされていない可能性があります。あるいは、あなたの過去には、大声でアンチデータベースの環境に没頭したことがあるかもしれません (例えば、「あの DBA はばかだ - 私たちの数は少ない。私たちが選んだ Java/C# コードスリンガーは、その日を救うだろう」)。 FK (および FK が暗示する制約) は、耳を傾けるだけなら本当に重要であると言っているドウィーブの難解なせせらぎに。

ほとんどの人は子供の頃、歯を磨くことが重要だと教えられました。それなしでやっていけますか?確かに、しかしどこかで、毎食後にブラッシングした場合よりも利用できる歯が少なくなります. お母さんとお父さんがデータベースの設計と口腔衛生をカバーするのに十分な責任を負っていたら、この会話はありませんでした. :-)

于 2008-09-17T16:55:17.437 に答える
54

それを回避できるアプリケーションはたくさんあると思いますが、それは最善のアイデアではありません。アプリケーションが常にデータベースを適切に管理できるとは限りません。率直に言って、データベースの管理はアプリケーションにとってあまり重要ではありません。

リレーショナルデータベースを使用している場合は、いくつかの関係を定義する必要があるようです。残念ながら、この態度 (外部キーは必要ありません) は、多くのアプリケーション開発者に受け入れられているようです。アプリケーション開発者は、データの整合性などのばかげたことに煩わされることはありません (ただし、会社には専任のデータベース開発者がいないため、気にする必要があります)。通常、これらのタイプでまとめられたデータベースでは、主キーを持っているだけで幸運です ;)

于 2008-09-17T13:38:10.450 に答える
42

外部キーは、どのリレーショナル データベース モデルにも不可欠です。

于 2008-09-17T13:29:34.013 に答える
29

私はいつもそれらを使用していますが、金融システムのデータベースを作成しています。データベースは、アプリケーションの重要な部分です。金融データベースのデータが完全に正確でない場合、コード/フロントエンドの設計にどれだけの労力を費やしても、実際には問題になりません。あなたはただ時間を無駄にしています。

また、データを読み取るだけの他のシステム (Crystal Reports) から、データを挿入するシステム (必ずしも私が設計した API を使用する必要はありません。 VBScript を発見したばかりで、SQL ボックスの SA パスワードを持っている愚かな管理者)。データベースが可能な限りばかではない場合は、さようならデータベースです。

データが重要な場合は、そうです。外部キーを使用し、一連のストアド プロシージャを作成してデータを操作し、できる限り頑丈な DB を作成します。データが重要でない場合、そもそもデータベースを作成する理由は何ですか?

于 2008-09-17T13:40:21.943 に答える
22

更新:私は常に外部キーを使用しています。「複雑なテスト」という反対意見に対する私の答えは、「データベースをまったく必要としないように単体テストを作成することです。データベースを使用するテストでは、データベースを適切に使用する必要があり、外部キーも含まれます。セットアップが面倒な場合は、セットアップを行うためのより簡単な方法を見つけてください。」


外部キーは自動テストを複雑にします

外部キーを使用しているとします。「金融口座を更新すると、取引の記録が保存されるはずです」という自動テストを作成しています。このテストでは、2つのテーブルのみに関心があります:accountstransactions

ただし、accountsに外部キーがcontractsあり、contractsにfkがありclientsclientsにfkがありcitiescitiesにfkがありstatesます。

これで、データベースでは、テストに関係のない4つのテーブルにデータを設定せずにテストを実行することはできなくなります

これには、少なくとも2つの考えられる視点があります。

  • 「それは良いことです。テストは現実的である必要があり、それらのデータの制約は本番環境に存在します。」
  • 「それは悪いことです。他の部分を関与させることなく、システムのテスト部分を単体化できるはずです。システム全体の統合テストを追加できます。」

テストの実行中に外部キーチェックを一時的にオフにすることも可能です。MySQLは、少なくともこれをサポートしています。

于 2012-10-26T13:11:25.317 に答える
16

「レコードの削除がより面倒になる可能性があります。外部キーがその制約に違反する他のテーブルにレコードがある「マスター」レコードを削除することはできません。」

SQL 標準では、外部キーが削除または更新されたときに実行されるアクションが定義されていることに注意してください。私が知っているものは次のとおりです。

  • ON DELETE RESTRICT- この列にキーを持つ他のテーブルの行が削除されないようにします。これは、ケン・レイが上で説明したものです。
  • ON DELETE CASCADE- 他のテーブルの行が削除された場合は、このテーブルでそれを参照しているすべての行を削除します。
  • ON DELETE SET DEFAULT- 他のテーブルの行が削除された場合、それを参照する外部キーを列のデフォルトに設定します。
  • ON DELETE SET NULL- 他のテーブルの行が削除された場合、このテーブルでそれを参照しているすべての外部キーを null に設定します。
  • ON DELETE NO ACTION- この外部キーは、それが外部キーであることを示すだけです。つまり、OR マッパーで使用します。

これらの同じアクションは、 にも適用されON UPDATEます。

デフォルトは、使用しているサーバーによって異なるようです。

于 2008-09-17T13:59:23.443 に答える
14

@imphasing - これはまさに、メンテナンスの悪夢を引き起こす一種の考え方です。

せいぜい弱い予防手段であるいわゆる「ソフトウェア強制」を支持して、データが少なくとも一貫性があることを保証できる宣言的な参照整合性を無視するのはなぜですか。

于 2008-09-17T13:36:15.107 に答える
12

それらを使用しない正当な理由が 1 つあり ます。それらの役割や使用方法を理解していない場合です。

間違った状況では、外部キーの制約により、偶発的なウォーターフォールの複製が発生する可能性があります。誰かが間違ったレコードを削除した場合、それを元に戻すのは膨大な作業になる可能性があります。

また、逆に、何かを削除する必要がある場合、設計が不十分な場合、制約によってあらゆる種類のロックが発生し、それが妨げられる可能性があります。

于 2008-09-17T13:34:04.813 に答える
10

それらを使用しない正当な理由はありません...孤立した行があなたにとって大したことではない場合を除きます。

于 2008-09-17T13:27:57.793 に答える
5

私の経験から、データベースの重要なアプリケーションでは FK を使用しない方が常に良いと言えます。ここで、FK は優れたプラクティスであるが、データベースが巨大で 1 秒あたりの CRUD 操作が膨大な場合は実用的ではないと言う人たちに異論はありません。名前を付けずに共有できます... の最大の投資銀行の 1 つは、データベースに単一の FK を持っていません。これらの制約は、プログラマーが DB を含むアプリケーションを作成する際に処理します。基本的な理由は、新しい CRUD が実行されるたびに、複数のテーブルに影響を与え、挿入/更新ごとに検証する必要があるためです。これは、単一の行に影響するクエリでは大きな問題にはなりませんが、対処するときに大きなレイテンシが発生します。大手銀行が日常業務として行うバッチ処理。

FK は避けたほうがよいですが、そのリスクはプログラマーが処理する必要があります。

于 2014-10-13T10:02:02.170 に答える
4

より大きな質問は、目隠しをして運転しますか? 参照制約のないシステムを開発する場合は、このようになります。ビジネス要件の変更、アプリケーション設計の変更、コード内のそれぞれの論理的仮定の変更、ロジック自体のリファクタリングなどがあることに注意してください。一般に、データベースの制約は、特定の一連の論理的アサーションと仮定に対して一見正しいように見える、現代の論理的仮定の下で設定されます。

アプリケーションのライフサイクルを通じて、特に新しい要件によって論理的なアプリケーションの変更が行われる場合、参照およびデータ チェックの制約により、アプリケーションを介したデータ収集が規制されます。

このリストの主題に対して- 外部キーはそれ自体で「パフォーマンスを向上させる」ことも、リアルタイム トランザクション処理システムの観点から「パフォーマンスを大幅に低下させる」こともありません。ただし、大量の「バッチ」システムでは、制約チェックに総コストがかかります。リアルタイムとバッチのトランザクション プロセスの違いは次のとおりです。バッチ処理 - 順次処理されるバッチの制約チェックによって発生するコストの増加により、パフォーマンスが低下します。

適切に設計されたシステムでは、バッチを処理する「前に」データの整合性チェックが行われます (ただし、ここにもコストがかかります)。したがって、ロード時に外部キー制約のチェックは必要ありません。実際、外部キーを含むすべての制約は、バッチが処理されるまで一時的に無効にする必要があります。

QUERY PERFORMANCE - テーブルが外部キーで結合されている場合、外部キー列がインデックス化されていないことに注意してください (それぞれの主キーは定義によりインデックス化されています)。さらに言えば、外部キーにインデックスを付けることで、任意のキーにインデックスを付け、インデックス付きでテーブルを結合すると、外部キー制約のあるインデックスなしのキーで結合するのではなく、パフォーマンスが向上します。

件名を変更すると、データベースが Web サイトの表示/コンテンツのレンダリング/その他をサポートし、クリックを記録するだけの場合、すべてのテーブルに完全な制約があるデータベースは、そのような目的には過剰です。考えてみてください。ほとんどの Web サイトは、そのようなデータベースを使用していません。データが記録されているだけで参照されていない同様の要件については、制約のないインメモリ データベースを使用します。これは、データ モデルが存在しない、論理モデルは存在するが、物理データ モデルが存在しないという意味ではありません。

于 2009-10-04T05:52:43.437 に答える
3

データの一貫性を維持するのに役立つという点で、以前の回答に同意します。ただし、数週間前に Jeff Atwoodが、正規化された一貫性のあるデータの長所と短所について論じた興味深い投稿がありました。

簡単に言えば、非正規化されたデータベースは、大量のデータを処理する場合により高速になります。アプリケーションによっては正確な一貫性を気にしないかもしれませんが、DB は気にしないので、データを扱うときはもっと注意する必要があります。

于 2008-09-17T13:33:40.713 に答える
3

Clarify データベースは、主キーまたは外部キーを持たない商用データベースの例です。

http://www.geekinterview.com/question_details/18869

面白いことに、技術文書は、テーブルがどのように関連しているか、それらを結合するためにどの列を使用するかなどを説明するために非常に長い時間を費やしています.

つまり、明示的な宣言 (DRI) を使用してテーブルを結合することもできましたが、結合しないことを選択しました

その結果、Clarify データベースは不整合でいっぱいになり、パフォーマンスが低下します。

しかし、削除や追加の前に関連する行をチェックするなど、参照整合性を処理するコードを書く必要がなくなり、開発者の仕事が楽になったと思います。

これが、リレーショナル データベースに外部キー制約がないことの主な利点だと思います。少なくともデビルメイケアの観点からは、開発が容易になります。

于 2008-09-17T13:34:29.447 に答える
2

外部キーを使用するその他の理由: - データベースの再利用を促進

外部キーを使用しないその他の理由: - 再利用を減らすことで、顧客をツールに閉じ込めようとしています。

于 2008-09-17T15:17:56.780 に答える
2

レコードの削除がより面倒になる可能性があります。外部キーがその制約に違反する他のテーブルにレコードがある「マスター」レコードを削除することはできません。トリガーを使用してカスケード削除を行うことができます。

主キーを賢明に選択しなかった場合、その値の変更はさらに複雑になります。たとえば、「顧客」テーブルの PK を人の名前として持っていて、そのキーを「注文」テーブルの FK にすると、顧客が自分の名前を変更したい場合、それは非常に面倒なことです.. . しかし、それはただのデータベース設計です。

Fireign キーを使用する利点は、想定される欠点を上回ると思います。

于 2008-09-17T13:31:08.470 に答える
2

外部キー制約の検証には CPU 時間がかかるため、パフォーマンスを向上させるために外部キーを省略する人もいます。

于 2008-09-17T13:34:15.623 に答える
2

私が知っているのは Oracle データベースだけで、他のデータベースは知りません。外部キーは、データの整合性を維持するために不可欠であることがわかります。データを挿入する前に、データ構造を作成し、正しく作成する必要があります。それが完了すると、すべての主キーと外部キーが作成され、作業は完了です。

意味: 孤立した行? いいえ、私の人生でそれを見たことはありません。悪いプログラマーが外部キーを忘れた場合、または別のレベルでそれを実装した場合を除きます。どちらも、Oracle のコンテキストでは、データの重複、孤立したデータ、つまりデータの破損につながる大きな間違いです。FK が強制されていないデータベースは想像できません。私にはカオスのように見えます。これは Unix の許可システムに少し似ています: 全員が root であると想像してください。混乱を考えてください。

外部キーは、主キーと同様に不可欠です。主キーを削除するとどうなるか? まあ、完全な混乱が起こるでしょう。それが何です。主キーまたは外部キーの役割をプログラミング レベルに移動することはできません。データ レベルで行う必要があります。

欠点?そのとおり !挿入時に、さらに多くのチェックが行われるためです。しかし、データの整合性がパフォーマンスよりも重要である場合、それは簡単なことではありません。Oracle でのパフォーマンスの問題は、PK および FK に付属するインデックスに関連しています。

于 2014-11-23T14:01:56.697 に答える
1

私にとって、 ACID標準に準拠したい場合は、参照整合性を確保するために外部キーを用意することが重要です。

于 2008-09-17T14:13:02.177 に答える
1

ここでコメントのほとんどを 2 番目に挙げる必要があります。外部キーは、データの整合性を確保するために必要な項目です。ON DELETE と ON UPDATE のさまざまなオプションを使用すると、使用に関してここで言及されている「ダウンフォール」のいくつかを回避できます。

すべてのプロジェクトの 99% で、データの整合性を確保するために FK を使用することがわかりましたが、クライアントが古いデータを保持しなければならない場合がまれにあります。しかし、とにかく有効なデータのみを取得するためのコードを書くのに多くの時間を費やしているため、無意味になります。

于 2008-09-17T14:17:50.763 に答える
1

アプリケーションのライフサイクル全体での保守性と一貫性はどうですか? ほとんどのデータは、それを利用するアプリケーションよりも寿命が長くなります。関係とデータの整合性は非常に重要であり、次の開発チームがアプリのコードで正しく理解することを期待することはできません。自然な関係を尊重しない汚れたデータを含むデータベースで作業したことがない場合は、そうするでしょう。データの整合性の重要性は非常に明確になります。

于 2008-09-17T16:08:21.027 に答える
1

ここで回答している人の多くは、参照制約によって実装された参照整合性の重要性に夢中になっています。参照整合性を備えた大規模なデータベースでの作業は、うまく機能しません。Oracle はカスケード削除が特に苦手なようです。私の経験則では、アプリケーションはデータベースを直接更新してはならず、ストアド プロシージャを介して更新する必要があります。これにより、コード ベースがデータベース内に保持され、データベースの整合性が維持されます。

多くのアプリケーションがデータベースにアクセスしている可能性がある場合、参照整合性制約のために問題が発生しますが、これは制御にかかっています。

アプリケーション開発者は、データベース開発者が必ずしも精通しているとは限らない非常に異なる要件を持っている可能性があるという点で、より広い問題もあります。

于 2013-03-26T17:55:27.330 に答える
1

私が聞いた議論では、フロントエンドにはこれらのビジネス ルールが必要だというものです。そもそも制約を破る挿入を許可してはならない場合、外部キーは「不要なオーバーヘッドを追加」します。私はこれに同意しますか?いいえ、しかしそれは私がいつも聞いていることです。

編集:私の推測では、彼は外部キーではなく、外部キーの制約を概念として参照していました。

于 2008-09-17T13:32:07.610 に答える
1

私はドミトリーの答えを繰り返します-非常によく言えます。

FK がしばしばもたらすパフォーマンスのオーバーヘッドを心配している人のために、(Oracle では) 挿入、削除、または更新中の制約検証のコスト オーバーヘッドなしで、FK 制約のクエリ オプティマイザーの利点を得ることができる方法があります。つまり、属性 RELY DISABLE NOVALIDATE を使用して FK 制約を作成します。これは、クエリ オプティマイザーが、データベースが実際に制約を適用することなく、クエリを作成するときに制約が適用されたと想定することを意味します。このような FK 制約をテーブルに入力するときは、FK 列に制約に違反するデータがないことを確実にするために、責任を負うようにここで非常に注意する必要があります。この FK 制約がオンになっているテーブルを含むクエリから、信頼できない結果が得られる可能性があります。

私は通常、データ マート スキーマの一部のテーブルでこの戦略を使用しますが、統合ステージング スキーマでは使用しません。データのコピー元のテーブルに既に同じ制約が適用されているか、ETL ルーチンが制約を適用していることを確認します。

于 2008-09-17T16:58:36.727 に答える
1

また、ほとんどのデータベースでは外部キーが必要だと思います。唯一の欠点 (強制的な一貫性に伴うパフォーマンス ヒット以外) は、外部キーを使用すると、機能する外部キーがあることを前提としたコードを記述できることです。それは決して許されるべきではありません。

たとえば、参照先のテーブルに挿入するコードを書いてから、最初の挿入が成功したことを確認せずに、参照先のテーブルに挿入を試みる人を見てきました。後で外部キーを削除すると、データベースの一貫性が失われます。

また、更新または削除時に特定の動作を想定するオプションもありません。外部キーが存在するかどうかに関係なく、必要なことを行うにはコードを記述する必要があります。削除がカスケードされていないのにカスケードされていると想定すると、削除は失敗します。参照された列への更新が、参照している行に反映されていないのに反映されていると想定すると、更新は失敗します。コードを書く目的では、これらの機能を持っていないこともあるでしょう。

これらの機能がオンになっている場合、コードはとにかくそれらをエミュレートし、パフォーマンスが少し低下します。

要約すると.... 一貫したデータベースが必要な場合、外部キーは不可欠です。外部キーは、記述したコード内に存在または機能すると想定しないでください。

于 2008-09-17T16:23:39.493 に答える
0

ドミトリーが言ったことを繰り返しますが、ポイントを追加します。

私は、30 以上のテーブルに大量の行セットを挿入する必要があるバッチ請求システムに取り組んでいました。データ ポンプ (Oracle) を実行することは許可されていなかったため、一括挿入を行う必要がありました。これらのテーブルには外部キーがありましたが、関係が壊れていないことは既に確認済みです。

挿入の前に、外部キー制約を無効にして、Oracle が挿入に永遠に時間がかからないようにします。挿入が成功したら、制約を再度有効にします。

PS: 多くの外部キーと 1 つのレコードの子行データを含む大規模なデータベースでは、外部キーが不適切な場合があり、カスケード削除を禁止したい場合があります。請求システムでは、カスケード削除を行うと時間がかかりすぎてデータベースに負担がかかりすぎるため、メイン ドライバー (親) テーブルのフィールドでレコードを不良としてマークするだけです。

于 2008-09-17T16:08:22.633 に答える
0

多くのものと同様に、それはトレードオフです。データの整合性を検証する作業をどこで行うかが問題です。

(1) 外部キーを使用する (テーブルを構成するための単一ポイント、機能は既に実装され、テストされ、機能することが証明されています)

(2)データベースのユーザーに任せます(複数のユーザー/アプリが同じテーブルを更新する可能性があります。これは、潜在的な障害点が増え、テストの複雑さが増すことを意味します)。

データベースが (2) を実行する方が効率的であり、(1) を使用すると保守が容易になり、リスクが少なくなります。

于 2008-09-18T04:17:27.513 に答える
0

データ構造設計の優れた原則の 1 つは、テーブルまたはオブジェクトのすべての属性が十分に理解された制約に従うようにすることです。これは重要です。ユーザーまたはユーザーのプログラムがデータベース内の有効なデータを信頼できる場合、不正なデータが原因でプログラムに問題が発生する可能性が低くなるからです。また、エラー状態を処理するためのコードを記述する時間が短縮され、エラー処理コードを前もって記述する可能性が高くなります。

多くの場合、これらの制約はコンパイル時に定義できます。その場合、属性が常に範囲内に収まるようにフィルターを記述できます。そうしないと、属性を保存しようとして失敗します。

ただし、多くの場合、これらの制約は実行時に変更される可能性があります。たとえば、最初は「赤」、「緑」、「青」の値をとる属性として「色」を持つ「車」テーブルがあるとします。プログラムの実行中にその初期リストに有効な色を追加することが可能であり、追加された新しい「車」は最新の色リストの任意の色を帯びることがあります。さらに、通常、この更新された色のリストは、プログラムの再起動後も存続する必要があります。

あなたの質問に答えるために、実行時に変更できるデータ制約の要件があり、それらの変更がプログラムの再起動後も存続する必要がある場合、外部キーが問題に対する最も単純で簡潔な解決策であることがわかります。開発コストは 1 つのテーブルの追加 (例: "colours"、"cars" テーブルへの外部キー制約、およびインデックス) であり、ランタイム コストは最新の色のための余分なテーブル ルックアップです。この実行時のコストは通常​​、インデックス作成とキャッシュによって軽減されます。

これらの要件に外部キーを使用しない場合は、リストを管理し、有効なエントリを検索し、ディスクに保存し、リストが大きい場合はデータを効率的に構造化し、リストへの更新が行われないようにするためのソフトウェアを作成する必要があります。リスト ファイルを破損させたり、複数のリーダーやライターが存在する場合にリストへのシリアル アクセスを提供したりします。つまり、多くの RDBMS 機能を実装する必要があります。

于 2010-06-11T19:27:26.040 に答える
0

FK が問題を引き起こす可能性があるのは、キーを使用する必要がなくなったにもかかわらず、キーを参照する履歴データが (ルックアップ テーブル内に) ある場合です。
明らかに、解決策は物事を前もってより良く設計することですが、私はここで、完全な解決策を常に制御できるとは限らない現実の状況について考えています。
たとえば、customer_typeさまざまなタイプの顧客を一覧表示するルックアップ テーブルがあるとします。たとえば、特定の顧客タイプを削除する必要があるが、(業務上の制約により) クライアント ソフトウェアを更新できず、誰もこの状況に気付かなかったとします。ソフトウェアを開発するとき、それが他のテーブルの外部キーであるという事実により、行を参照する履歴データが無関係であることを知っていても、行を削除できない場合があります。
これで数回やけどを負った後、おそらく関係のデータベース強制から遠ざかります。
(これが良いと言っているのではありません。一般的に、FK と db 制約を避けることに決めた理由を示しているだけです)

于 2008-09-17T13:55:18.430 に答える
0

私が取り組んだプロジェクトでは、多くのテーブルを同じ列で結合できるように、明示的ではなく暗黙的な関係がしばしばありました。

次の表を取る

住所

  • アドレス ID (PK)
  • エンティティ ID
  • エンティティ タイプ
  • 等..

EntityType の可能な値は、Employee、Company、Customer である可能性があり、EntityId は、関心のあるテーブルの主キーを参照します。

これが最善の方法だとは思いませんが、このプロジェクトではうまくいきました。

于 2012-08-22T22:50:16.207 に答える
0

DB2 では、MQT (Materialized Query Tables) が使用されている場合、オプティマイザーが特定のクエリに対して適切なプランを選択するには、外部キー制約が必要です。それらにはカーディナリティ情報が含まれているため、オプティマイザーはメタデータを多用して MQT を使用するかどうかを判断します。

于 2013-12-04T18:47:38.713 に答える
0

私もこの議論を聞いたことがあります。外部キーにインデックスを付けるのを忘れて、特定の操作が遅いと不平を言った人からです (制約チェックが任意のインデックスを利用する可能性があるため)。要約すると、外部キーを使用しない正当な理由はありません。最新のデータベースはすべてカスケード削除をサポートしているため...

于 2008-09-17T13:38:46.923 に答える
0

非常に頻繁に FK 制約でエラーを受け取ります を追加または更新できません: 外部キー制約が失敗しますレコードが contract_lines に既に存在するか、ベース テーブルから PK 列を削除したい場合、FK 制約のエラーが発生します。以下に示す手順を使用して回避できます。

CREATE TABLE inventory_source (
inventory_source_id int(11) NOT NULL AUTO_INCREMENT,
display_name varchar(40) NOT NULL,
state_id int(11) NOT NULL,
PRIMARY KEY (inventory_source_id),
KEY state_id (state_id),
CONSTRAINT ba_inventory_source_state_fk FOREIGN KEY (state_id) REFERENCES   ba_state (state_id)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

CREATE TABLE contract_lines(
contract_line_id int(11) NOT NULL AUTO_INCREMENT,
inventory_source_id int(11) NULL ,
PRIMARY KEY (contract_line_id),
UNIQUE KEY contract_line_id (contract_line_id),
KEY AI_contract_line_id (contract_line_id),
KEY contract_lines_inventory_source_fk (inventory_source_id),
CONSTRAINT contract_lines_inventory_source_fk FOREIGN KEY       (inventory_source_id) REFERENCES ba_inventory_source (inventory_source_id)
) ENGINE=InnoDB AUTO_INCREMENT=135 DEFAULT CHARSET=utf8 ;

次の手順を使用してそれを克服できます。

  1. inventory_source から行を削除または更新すると、contract_lines テーブル内の一致する行が自動的に削除または更新されます。これはカスケード削除または更新と呼ばれます。
  2. もう 1 つの方法は、inventory_source テーブルで対応するレコードが削除されたときに、contract_lines テーブルの inventory_source_id 列を NULL に設定することです。
  3. 親テーブルの削除または更新を制限できます。つまり、inventory_source テーブルの削除または更新操作を拒否できます。
  4. 参照されるテーブルに関連する外部キー値がある場合、主キー値を削除または更新しようとしても続行できません。
于 2015-04-15T07:38:38.127 に答える
-1

私はいつもそれらを使わないのは怠け者だと思っていました. 必ずやるべきだと教わりました。しかし、その後、私はジョエルの議論を聞きませんでした. 彼には正当な理由があったのかもしれませんが、私にはわかりません。

于 2008-09-17T13:29:58.413 に答える
-9

外部キーを使用する理由はいくつかありますが (誰かが言ったように、孤立した行は面倒です)、私もそれらを使用したことはありません。比較的健全な DB スキーマでは、それらが 100% 必要だとは思いません。制約は良いですが、ソフトウェアを介して強制する方が良い方法だと思います。

アレックス

于 2008-09-17T13:32:11.183 に答える