28

さまざまな雇用主で働いた後、私はこれらの会社のいくつかで「悪い」データベース設計の傾向に気づきました-主に外部キー制約の除外。これらのトランザクションシステムにFKがないことは常に私を悩ませてきました。これにより、参照整合性が促進されます。

  • トランザクションシステムで、FKを省略することが有益であるシナリオはありますか?

  • 他の誰かがこれを経験したことがありますか?もしそうなら、結果はどうでしたか?

  • 彼らがこのシナリオを提示され、システムを維持/強化するように求められた場合、どうすればよいですか?

4

6 に答える 6

46

2つの列に依存関係がある場合、それらの間にFK制約を設定するべきではないというシナリオは考えられません。参照整合性を削除すると、データベース操作が確実に高速化される可能性がありますが、その費用はかなり高くなります。

そのようなシステムを経験しましたが、通常の結果は、存在してはならないレコードが存在するという意味で(またはその逆)、データが破損しています。これらは、アプリケーションがそれを処理し、それを気にしないので、人々が大丈夫だと信じる種類のシステムです。

  • 1台のDBサーバーではなく、すべてのアプリケーションがそれを処理する必要があります。
  • 誰にとってもそれを台無しにするのに必要なのは、1つのバグまたは悪性アプリだけです。
  • それ自体を保護するのはデータベースの責任です!それはその最高の機能の1つです。

あなたが何をすべきかについて、私は単にうまくいかない可能性のあることと、FKを使用することでそれを防ぐ方法を提案します(多くの場合、必要に応じて、費用便益分析が私の視点に向かって「歪曲」されます)。それから会社に決めさせてください-結局のところ、それは彼らのデータベースです。

于 2012-08-22T02:22:47.820 に答える
12

適切に作成されたアプリケーションは参照整合性を必要としないという考え方があります。アプリケーションが正しく機能する場合、考え方は変わります。制約は必要ありません。

このような考え方は、コードを正しく記述すればバグが発生しないため、防御的なプログラミングを行わないことに似ています。本当ですが、それは単に起こりません。適切な制約を使用しないと、データの破損が発生します。

あなたがすべきことに関しては、あなたは会社にあらゆる機会に制約を加えるように勧めるべきです。トラブルに巻き込まれたり、自分に悪い名前を付けたりするほどプッシュしたくはありませんが、環境が適切である限り、プッシュし続けてください。長い目で見れば、みんなの生活は良くなるでしょう。

于 2012-08-22T02:33:24.093 に答える
5

個人的には、データベースに外部キーの明示的な宣言がなくても問題はありません。ただし、データベースがどのように使用されているかによって異なります。

私が使用しているデータベースのほとんどは、1つ以上のトランザクションシステムから派生した比較的静的なデータです。私はデータベースに影響を与える不正な更新には特に関心がないので、外部キー関係の明示的な定義は特に重要ではありません。

私が持っていることの1つは、非常に一貫した命名です。基本的に、すべてのテーブルにはIDと呼ばれる最初の列があります。これは、他のテーブルで列が参照される方法とまったく同じです(または、2つのエンティティ間に複数の関係がある場合は、プレフィックスが付いている場合もあります)。また、そのようなデータベースのすべての列には、属性を説明する一意の名前があることを主張しようとしています(したがって、「CustomerStartDate」は「ProductStartDate」とは異なります)。

「鍋の中の料理人」が多いデータを扱っている場合は、外部キーの関係についてより明確にしたいと思います。そして、私は外部キー定義のオーバーヘッドをもっと喜んで持っています。

このオーバーヘッドは多くの場所で発生します。新しいテーブルを作成するときは、「テーブルの作成」または「選択」を使用して、制約の詳細を気にしないでください。更新クエリまたは挿入クエリを実行するときに、問題がないことがわかっていることをチェックするデータベースのオーバーヘッドが必要ない場合があります。ただし、一貫した命名により、問題がないという自信が大幅に高まることを強調する必要があります。

明らかに、私の視点はDBAの視点ではなく、実務家の視点です。ただし、テーブル間の無効な関係は、私(またはチームの他のメンバー)が対処する必要がほとんどないものです。

于 2012-08-22T02:35:47.897 に答える
3

データベースへの単一のエントリポイントがある限り、最終的には、どの「レイヤー」が参照整合性を維持しているかは関係ありません。外部キー制約の「組み込み層」を使用するのが最も理にかなっているようですが、同じことを担当する堅実なサービス層がある場合は、必要に応じてルールを破る自由があります。

個人的には、外部キー制約を使用してアプリを設計しているため、ルールに違反する必要はありません。参照整合性が保証されたリレーショナルデータは、操作が簡単です。

向上したパフォーマンスは、データベースの外部で整合性を維持する必要があるために失われたパフォーマンスとおそらく同等です。

于 2014-10-14T21:24:26.070 に答える
2

OLTPデータベースで私が考えることができる唯一の理由は、データの整合性よりもパフォーマンスを重視する場合です。行が子テーブルに挿入されるときにFKを適用するには、親テーブルでのインデックスシークが必要であり、この比較的高速なインデックスシークでさえ多すぎるという極端な状況が発生する可能性があると想像できます。たとえば、ある種の非常に集中的なロギングでは、誤ったログエントリが存在する可能性があり、書き込みを行うアプリケーションは単純であり、バグが発生する可能性はほとんどありません。

そうは言っても、破損したデータを抱えて生きることができれば、そもそもデータベースがなくても生きることができるでしょう。

于 2012-08-22T08:14:26.200 に答える
0

外部キーを使用しない防御プログラミングは、主にストアドプロシージャを使用し、すべてのアプリケーションが独自のクエリを作成する代わりにそれらのストアドプロシージャを使用する場合に機能します。そうすれば、標準の外部キーよりも非常に簡単かつ柔軟に制御できます。

外部キー制約を簡単に使用できない状況の1つは、ブール値によって決定されるユーザーごとまたはグループごとにアクセス許可を適用できるアクセス許可モジュールです。したがって、権限テーブルの一部のレコードにはユーザーIDがあり、他のレコードにはグループIDがあります。それでも外部キー制約が必要な場合は、同じ相互排他情報に対して2つの異なるフィールドを用意し、それらをnullにできるようにする必要があります。1つをnullにすることは許可されているが、両方をnullにすることはできないという別の制約を追加することを意味します。また、2つのフィールド(ユーザー/グループIDとアクセス許可ID)の組み合わせではなく、3つのフィールドの組み合わせが一意である必要があります。また、同じデータを含む2つの別個のテーブルを使用することもできます。つまり、両方のテーブルを別々に維持します。

しかし、おそらくそのシナリオでは、データを分離するのが最善です。そのレコード内の他のデータに基づいて異なるテーブルに接続するために同じフィールドが必要な場合は、外部フィールド制約を使用できません。代わりに、ストアドプロシージャとビューに制約を保持するのが最善です。

于 2018-08-03T17:42:15.277 に答える