リレーショナルデータベースの制約-完全に削除しないのはなぜですか?


20

最近(SQLserver内の)テーブル間に制約を作成する理由はありますか?もしそうなら、いつ?私の分野のほとんどのアプリケーションはオブジェクトの原則に基づいて構築されており、テーブルは必要に応じて結合されます。需要は、アプリケーションのニーズに基づいています。単純なルックアップのために束縛されたテーブルをロードすることはありません。順番に(アクションの後)別の単純なルックアップが必要です。

EntityContext、Linq2Data、NHibernateなどのORMツールも、それ自体で制約を処理します。少なくとも、相互に必要なテーブルはわかっています。サーバー内で制約を行うことは、同じ変更を2回行う(強制する)だけのことですか?

これは通常、決定に疑問を投げかけるものではありませんが、このデータベースはまったく異なる設計になっています。設計は通常のように見えますが、ほとんどはアプリケーションで使用されるオブジェクトをミラーリングしています。私を悩ませているのは、SQLserver内で「カスケードなし」に設定されたすべての制約です。つまり、新しいデータベースクエリをコーディングするときは、「検索して検索」する必要があります。場合によっては、1回の削除を行うために最大10レベルの正確な順序が必要です。

これは私を驚かせます、そして、私はそれをどう扱うべきかわかりません。

私の単純な世界では、この設定により、制約のほとんどの目的が失われます。設計に関する知識がなくてもデータベースにホストからアクセスした場合はOKです。

このシナリオでどのように行動しますか?
dbからすべての制約を削除して、アプリケーションレベルで保持しないのはなぜですか。


6
常に単一のORMツールを介してデータにアクセスすることを計画していましたか?または、使用中の各ORMツール全体ですべての制約を正しく「楽しく」複製することを計画していましたか?
ドナルドフェローズ

1
ピーターへの私の最新のコメントごとに、私は同意しなければなりません。すべての制約をコードベースに依存する(そしてそれらをdbから削除する)ポイントは非常に狭く、おそらく短命のアプリケーションに完全に適用できます。おそらく一部のRAD開発者/プロジェクトにも。
独立

4
ちょっとした注意:テーブル間の外部キー接続を「関係」と呼ぶと、少し混乱を招くと思います。リレーショナルデータベースの「関係」はテーブルではなく、接続です。特に、「リレーショナル設計」について話をするとき、それはテーブルを意味しますか、それとも外部キーを意味しますか?
トーマスパドロンマッカーシー

ありがとう。制約を「テーブル間の接続」と呼びます。したがって、おそらく、テーブル設計の原則(テーブルの構造)について「リレーショナルデータベース」を参照することは間違いありません。「関係対オブジェクト」データベースに関連する場合、さらに正確な説明は「設計パターン」になります。
独立

1
データベースは、アプリケーションコードよりも長持ちします。また、ORMによってアプリケーションのパフォーマンスが低下しているため、少なくとも特定のユースケースではバイパスすることになる可能性が高くなります。あなたが今それを知らないならば、あなたは結局それを知るでしょう。samsaffron.com/archive/2011/03/30/...。また、すべての制約を削除すると、データベースが他のアプリによって悪用された場合、データベースが完全に保護できなくなります。これは、Excelを使用した実際の別のアプリから役員まで何でもかまいません。
クレイグ14

回答:


46

DBから制約を削除しない 2つの一般的な理由:

  • 現在または将来、ORMを使用する場合と使用しない場合があります。これらのアプリの開発者がすべての制約を忠実に複製したとしても(低レベルの非ORMソリューションを使用すると非常に困難になる可能性があります)、常に余分な作業になります。そうでない場合でもスキーマの整合性を壊すには1つの小さな省略で十分です...これはリスクを避けたいものです。ほとんどの企業では、DBに保存されているデータはビジネスの生命線であるため、あらゆる手段でその整合性を確保する必要があります。そして、これを達成するために試行され実証された最良の手段は、可能な限り多くの制約をDBに実装することです。
  • クエリオプティマイザーは、DBレベルで既知の制約に大きく依存しています。制約を削除すると、クエリのパフォーマンスが低下する可能性があります。すぐに気付かないかもしれませんが、いつかあなたにぶつかるでしょう。それまでに手遅れになり、簡単に修正することはできません。性質上、DBのパフォーマンスは、正確なパフォーマンス測定と根本原因を特定するための詳細な分析によって裏付けられた、慎重かつ熟考された設計改善を行う可能性が最も低いピーク負荷時に低下する傾向があります。

あなたの具体的なケースは、DBスキーマがORMツールによって最初に生成された(またはリレーショナルの世界にあまり詳しくない人によって設計された)ように聞こえるので、リレーショナルの観点からは最適ではありません。ORMビューとの一貫性を保ちながら、より「自然な」リレーショナルデザインに向けて分析および改善することをお勧めします。この分析にDBの専門家を関与させると役立つ場合があります。


5
@Jonas、それから彼のDB設計で認識されている問題について話します。リレーショナルとオブジェクト指向は2つの異なる世界です。どちらも「改善」自体ではなく、どちらも独自の場所を持っています。リレーショナルの原則に基づいたC#アプリの設計は、オブジェクト指向の方法でDBを設計するのと同じくらい大きな間違いです。
ペテルトレック

3
@Jonas、更新に反映:DBスキーマに対して一見単純なことを実現するために過度に複雑なクエリを記述する必要がある場合、DB設計がその目的に対して不十分であることを示すか、十分なスキルがないことを示します(ご注意ください)怒らないでください。あなたの投稿からSQLの経験が明らかではありません。免責事項として、私自身は専門家ではありません。)
PéterTörök11年

1
私はおそらく自分自身を知覚可能にするために、学ぶべきいくつかの表現を持っています:)。私は質問と回答を読み直し、逆にしなければなりません。すべての制約のマスターとしてDBを使用することには、間違いなく長所があります。すべてのシステムをそこから設計する必要があります。コードベースが作業を行うと言う非常に狭い見方。すべてのシステムが制約について独自の決定を行うことができる場合、間違った提案されたリレーションとテーブル全体が孤立した状態で、高チャップラーで終わることになります。今ではない場合、他のコーダーで後で発生します。
独立

8
「現在または将来、より多くのアプリからアクセスされる可能性があります。」ユーザーが待っている間にない、データベースとの問題を解決するために、生のSQLクエリを実行し、いくつかのデータベース管理者は言うまでもあり...
トーマスPadronの-マッカーシー

5
1:DBは、データベースがアウトライブ/または現在のアプリケーションの外に延長される確率が100%に近づいている、(だけでなく、アプリ設定など)業務データを格納している場合
バイナリ心配性

27

アプリケーションは行き来できますが、データは永遠に残ります。私の会社では、DBは30〜40歳以上であり、会社が存在する限り存続します。アプリケーションが変わり、開発者が出入りします。整合性と優れた論理データモデルを使用することをお勧めします。そうすれば、複雑なコードベースを経験することなく、誰かがデータを見て有意義な理解を得ることができます。これは、レポートの作成にも役立ちます。また、アプリケーションにはバグが存在する可能性があり、バグが発生する可能性があり、DB制約はそれに対するガードです。私のデフォルトの位置は、可能な限り多くの制約(FKとチェック)を持つことです。
制約を持たない唯一の理由は、設計パターンがそれを許可しない場合(たとえば、階層ごとのテーブルまたはパフォーマンスの問題)です。


ここで非常に賢明なアドバイスをしていると言います。私の意見は、RAD開発や、アプリケーションのライフタイムが短い場所で開発しているものによく一致するかもしれません-開発中の保守を最小限に抑えるためだけです。
独立

15

私を悩ませているのは、SQLserver内で「カスケードなし」に設定されたすべての制約です。

それは私を邪魔するものではありません。つまり、誰かが良識を示しているということです。カスケード削除は多くの場合、データベースにとって非常に悪いです。そもそも、関連テーブルにデータがある場合に削除を失敗させたい場合があります。たとえば、過去に注文した顧客がいる場合、その顧客を削除したり、注文の対象者に関するデータを失ったり、カスケード削除を行うと、財務報告を混乱させるレコードを削除できます。

開発者の容易さは最も重要なことだと思われるようです。データベースの世界では、これは単に真実ではありません。データの整合性は、パフォーマンスとデータのセキュリティが密接に続く最初の最も重要なことです。クエリの作成に時間がかかる場合は、そうしてください。

データベースは通常、多くのアプリケーション= 1つ以上のWebサイトまたはデスクトップアプリケーション、レポートアプリケーション、Webサービス、クエリウィンドウ、ETLプロセスなどによって処理されます。データベースレベルで制約を実施しない場合、最初に整合性が失われます。それらのアプリケーションの1つとしてのデータのすべてが、すべてのルールに従うとは限りません。第二に、後で別のアプリケーションを使用することにした場合は、これらの制約を複数回コーディングし、書き換える必要があります。第三に、アプリケーションを通じて発生しない何らかのデータ保守タスクを実行する必要があるかどうかを事前に制御することはできません会社が競合他社に買収されたときの別のクライアントへ)。通常、アプリケーション開発者は


返信ありがとうございます。あなたが話しているすべてのプロセスとアプリケーションの種類は、DALと通信する必要があります(これには制約が含まれます)。しかし!あなたのポイントは完璧であり、あなたのコメントは良いです。補足:はい。私は開発を容易にする方法を試す傾向があります。私にとっては、複雑さが少なければ、間違ったやり方を減らすことができます。これは、たとえそれが間違っていたとしても、「簡単/高速に開発したい」ということではありません。したがって、なぜこの質問を投稿するのですか!また、このシナリオのように100%ではなく、この非カスケードが合理的に選択された場合、誰かの良識を見るでしょう。理由を見つけなければなりません。
独立

@Jonas、パフォーマンス上の理由もあります。子レコードの数に依存します。小さなグループを削除しているが、何百万ものレコードがトリガーされる可能性がある場合は、バッチを実行し、プロセス全体が行われている間にすべてのテーブルをロックしない方が良いでしょう。一般に、多くのdbasは、削除があまりにも多くのレコードに影響する場合にprodシステムをロックする可能性があるため、その理由だけでカスケード削除を許可しません。
HLGEM

2
すべてのプロセスがDALと通信するべきではありません。ETLプロセスは、通常、データベースレベルで発生する必要はなく、何らかの大きな変更が発生したときに多くのレコードに影響を与えます(クライアントが買収されるなど)。また、クエリウィンドウを使用して1回限りの変更を行うことを禁止することもできません。長期間にわたって整合性の問題が発生しない、データベースレベルで制約を適用しないデータベースを見たことはありません。
HLGEM

10

私は基本的に言ったどこかを読んだ:データはあなたのアプリケーションの鍵です。あなたのUIでのみEVERアクセスデータがする場合は(と私が意味する、これまで、今と永遠のように、すべての永遠...またはアプリケーションの寿命のために、とにかく)あなたは、データベースの制約を必要としません。ただし、Webサービス、パブリックAPI、rakeタスク/ SQLジョブ/ cron /自動スクリプトなど、アプリ自体以外のものがデータに触れる必要がある可能性があります。そうすれば、潜在的なトラブルを大幅に軽減できます。 DBの制約を維持することにより、

これは、DRYを適用すべきではないソフトウェア開発の1つの領域であると固く信じてます(そして、私はその声明に対して多くのダウン票を期待しています)。データはアプリケーションの核心です-修復できないほど破損している場合、それはゲームオーバーです。IMOが必要とするすべての場所で制約を強制することは価値があります。DBレベルでのトリガーと制約、ミドルウェアでのサーバー側の検証、およびUI(Webアプリの場合)でのクライアント側のJavascriptの形式である場合、データが常に初期状態であることを保証するのはIMOにとって必要な悪です。


6

ORMの意味を知っていますか?オブジェクトリレーショナルマッピング。Wikipedia「互換性のない型システム間でデータを変換するためのテクニック」を引用。うん、リレーショナルとオブジェクトモデルは一緒に適合しません。ORMは、両方の型システムのルールを尊重することで、かなり良い変換を行います。RDBMSは、制約を使用してデータの整合性を実現するように編成されています。一般的に、整合性は非常に優れているため、ORMはオブジェクトデータを格納するためのデータモデルを作成するときにそれらを使用する傾向があります。ORMには、「非カスケード」制約を使用する正当な理由がある可能性があります。また、特定のオブジェクトを作成/更新/ドロップするだけでなく、複雑なクエリを作成する必要がある場合、ORMの設定に問題があります。

リレーショナルコンセプトが迷惑だと思うのなら、なぜオブジェクトデータベースを使用しないのですか?少し前までは速度が遅かったので(ほとんどの人がまだRDBMSを使用しているのですが)、私が聞いたことから物事は少し変わりました。あなたはすべてのリレーショナルニッピックを取り除くでしょう。単にオブジェクトを入力し、オブジェクトを出力します。


トピックは、DBから制約機能を削除し、コードベース内の設定/開発に依存することです(例:.net話す:Entity / Linq2Sql)。
独立

はい、わかっていますが、まず最初に制約が存在する理由を理解し、次にそれを削除するのが悪い考えである理由を理解する必要があるということです。
ヤチェクプルシア

動いた!落とされません。あなたが質問についての知識を後悔していることを理解していますが、それはそれではありませんでした。
独立

互換性のないシステム間で実際に何かを移動することはできません。DB制約を削除し、アプリケーション制約を導入し、それらが同じように機能することを単に望みます(これは、trueとfalseになります)。とにかくあなたの質問を誤解した場合、私の誠実な謝罪。
ヤチェクプルシア

ありがとう!「移動」とは、文字通り「移動」を意味します。つまり、すべてのシステムで(適切な表現の)アプリケーション制約を作成します。少なくとも同じDALを共有できない各システム。非常に良い例は、「何かを修正する」db管理者からの直接クエリです。dbの制約や設計知識の欠如は、孤立したデータや完全にモックアップされたデータになる可能性があります。
独立した

6

それがeBayが行ったことであり、おそらく世界最大のデータベースの1つを持っています。

http://www.dba-oracle.com/oracle_news/news_ebay_massive_oracle.htm http://www.addsimplicity.com/downloads/eBaySDForum2006-11-29.pdf

参照整合性によってパフォーマンスが向上するということについて上で述べてきたことにもかかわらず、実際には低下する可能性があります。これが、大規模なデータベースが制約を取り除き、アプリケーション層で作業を行っている理由です。そして私が知る限り、それが唯一の本当に正当な理由です。

これらの制約を削除すると、データをクリーンに保ち、それ自体の問題を引き起こすセーフティネットを本質的に失うことになります。すべてと同様に、それはバランスのとれた行為です。一般に、参照整合性を維持することは正しいことだと思います。

強い参照整合性を備えた開発環境で作業したことがあるので、開発者の観点から見ると、それが完全な苦痛になる可能性があることを知っています。多くの場合、開発環境では少しのダーティデータは重要ではなく、行を削除する方法を決めるのに1時間以上かかる場合があります。ただし、制約によりスキーマが明示されるため、非常に便利です。


最後に私を理解している誰か:-)。あなたは完全に正しい、バランスはここで本当に大きなポイントです。戦略的なポイントとして実行される場合、制約をアプリケーションレベルに移動することは安全な代替手段になる可能性があります。強力な制約/整合性のためにパフォーマンスが低下していることが証明されているサイトへのURLがあると便利です。
独立

10
はい、忘れないでください-忘れないでください -FacebookやAmazonのようなEbayは、データベースの99.99%の数百万倍です。
トニーアンドリュース

2
また、ebay、Facebook、Amazonは、財務および会計ソフトウェア、在庫ソフトウェア、またはHRデータ、またはデータを失わないことが重要な場所に制約のないデータベースを使用しない可能性があります。
HLGEM

2
十分な時間、専門知識、およびお金があれば、最終的には特定のニーズに合わせてRDBMS、Webサーバー、またはオペレーティングシステムをプログラミングできます。
-JeffO

1
eBayは、大量のデータが大量に処理され、データベースサーバーの対応能力を本質的に上回るまで、それを行わず、新しいアーキテクチャに何百万もの投資をしました。1日に数十億件のトランザクションを実行している場合は、必ず制約を取り除き、eBayのような完全にキューベースのトランザクションレスで非常にスケーラブルなシステムに移行することを検討してください。それ以外の場合は、データベースサーバーを過小評価しないでください。また、すべての制約を削除して、データベースをデータ破損の対象にしないでください。
クレイグ14

4

最初に-私の答え:いいえ、データの世話をするのにアプリケーションだけに頼るべきではありません。

これは、より大きな議論を指し示しています。ORMは、多くの場合、正規化/参照整合性を犠牲にして、「直接的な」DB相互作用に対する軽daの文化を奨励しています。テーブルは、リレーショナルモデルで暗黙的な設計を犠牲にして、任意のオブジェクト階層に強制的にマップされます。OOPが好むデカップリングは、アプリケーションがデータ構造でデザインを感じさせるため、ここではほぼ間違いなく犠牲になっています。ORMは優れた有用性を実証していますが、SQLの悪用または不信に基づいているようです。

新しいパラダイムは(再)出現しています。たとえば、関数型プログラミングを取り上げます。開発チームが新しいプログラミング方法論を採用することを決定した場合、ORMの要件に従って構造化されたデータにどのような影響がありますか?

@Jacek Pruciaに同意します。ORMはRDBMSによく合わないと思います。個人的にRDBMSでDBALを選択するか、ORMでOODBを選択します。


トピックの代替案を話すための+1。議論の反対側はもちろん「データがどれほど悪いのか」です。答えは、キャンセルまたは数百万ドルの銀行口座への数十億のお金の挿入です。同様に、適切なクリーニングルーチンで削除される孤立データもあります。このトピックの要約は、柔軟性のコストに対する一貫性のように見えます。これは、データベースのコンテンツと使用の重大度に完全に依存します。
独立

3

制約は、データベースレベルで一貫性とデータの整合性を確保する唯一の保証です。もちろん、アプリケーションコードを使用して制約を適用できますが、将来、データを直接変更する必要がある場合はどうでしょうか。データの整合性を維持する方法を理解しているかもしれませんが、他の誰かはそうではないかもしれません。制約をデータレベルで保持することで、誰かが理解できない場所でうろついている場合でも、整合性が保証されます。

さらに、アプリケーションを書き換える必要があるが、同じデータベースを使用する必要があるとしましょう。コード内のこれらの制約はすべて、誤ったデータの通過を許可しながら、一部のエントリを妨げるバグをただ懇願しています。

開発するときは、シンプルにしてください。制約により、それが可能になります。(つまり、制約がエラーをスローした場合、ユーザーに同じエラーを返さないでください。エラーを理解できるようにします。)

(カスケードの問題に関しては、それは良いことです。すべてを正しくするためにカスケードに依存するのではなく、最初に他の特定のレコードを削除する必要があるというエラーをスローすることを好みます。実際にはそうです。)


2

データベースの制約に関する問題の1つは、プログラムに障害の内容と修正方法に関する情報が限られていることです。これは、スムーズな処理のために、アプリケーションで制約チェックを繰り返す必要があることが多いため、データベースの制約チェックが無駄になることを意味します。

これは、データの整合性を損なう危険性があるため、ここでトレードオフがあります。重要なデータの場合、ほとんどの場合、データの整合性を確保することはパフォーマンスよりも重要であり、データを台無しにするよりもarbitrary意的に見える場合でもトランザクションを失敗させる方がはるかに優れています。

したがって、制約を安全に削除するには、データベースアクセスを保護して、制約をチェックしない限りデータベースを変更できないようにすることが重要です。新しいアプリケーションを作成するとき、またはデータを処理するアドホックな方法を考え出すとき、これは信頼できません。必要なのは1つの間違いであり、データベースが破損しているためです。

したがって、データベースの制約をなくすために、データベースでできることとできないことを前もって確立し、すべてのアプリケーションを広範囲に記述、レビュー、およびテストできるようにする必要があります。すべてのデータベース要件を事前に確立する必要があります。データベース要件を変更するには、広範な作業が必要です。これは凍結された滝の方法論の一種であり、非常に特定の場合にのみ機能します。(要件を設計、実装、および維持することは、水の上を歩くことに似ています。まず何かを凍結する必要があります。凍結しなければ、結果は悲惨なものになります。)

動作する1つのケースは、PeopleSoftやSAPのような大規模なエンタープライズアプリケーションです。このアプリケーションは、ほぼすべてをすでに実行しており、拡張する方法は慎重に定義されています。他にも非常にまれな可能性があります。

したがって、非常に大規模なエンタープライズプロジェクトに取り組んでいない場合(そして、私はそうしたくありません)、または液体の水の上を歩くことができる場合を除き、データベースにこれらの制約を残します。


1
返信ありがとうございます。制約はこのプロジェクトのデータベースにあります!私は完全に確信しています:)。また、将来のプロジェクトや他の部分との議論でこれを決定するとき、私はより広い目を持ちます。
独立

1
また、制約がなければ、アプリケーションコード自体に任せて、問題が発生したことを検出することも考慮してください。ちなみに、この例の制約に違反したのと同じアプリケーションコードは、データベースをデータの不整合や破損から保護した制約です。ところで、制約を使用しても自動的にパフォーマンスが低下することはありません。また、制約を使用しないと、データベースが公開されたままになり、データベース自体を保護できなくなります。
クレイグ14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.