web-dev-qa-db-ja.com

データベースの制約はどうなりましたか?

RDBMSのデータベースモデルを確認すると、通常、制約がほとんどない(PK/FKを除く)ことに驚きます。たとえば、パーセンテージはint型の列に格納されることが多く( tinyint の方が適切です)、CHECK制約はありません値を0..100の範囲に制限します。 SE.SEでも同様に、チェック制約を示唆する回答は、多くの場合 comments を受け取り、データベースが制約の不適切な場所であることを示唆します。

制約を実装しない決定について質問すると、チームメンバーは次のように応答します。

  • そのような機能がお気に入りのデータベースに存在することさえ知らないのかもしれません。 ORMのみを使用するプログラマからは理解できますが、特定のRDBMSで5年以上の経験があると主張するDBAからはあまり理解できません。

  • または、アプリケーションレベルでこのような制約を適用し、それらのルールをデータベースに複製することは、SSOTに違反してお勧めできません。

最近では、外部キーも使用されないプロジェクトが増えています。同様に、ここでSE.SEについていくつかのコメントを見ました 表示 ユーザーは参照整合性についてあまり気にせず、アプリケーションに処理を任せています。

FKを使用しない選択についてチームに尋ねるとき、彼らはそれを伝えます:

  • たとえば、他のテーブルで参照されている要素を削除する必要がある場合は、PITAです。

  • NoSQLは揺るがし、そこに外部キーはありません。したがって、RDBMSでは必要ありません。

  • これはパフォーマンスの点では大した問題ではありません(コンテキストは通常​​、小さなデータセットで動作する小さなイントラネットWebアプリケーションであるため、実際には、インデックスでさえあまり問題になりません。特定のクエリのパフォーマンスが1.5秒から渡っても問題ありません。 。〜20ミリ秒。)

アプリケーション自体を見ると、体系的に2つのパターンに気づきます。

  • アプリケーションはデータを適切にサニタイズし、データベースに送信する前にチェックします。たとえば、アプリケーションを通じて値102をパーセンテージとして保存する方法はありません。

  • アプリケーションは、データベースからのすべてのデータが完全に有効であることを前提としています。つまり、102がパーセンテージで表示される場合、何かがどこかでクラッシュするか、単にユーザーにそのまま表示されて、奇妙な状況につながります。

  • クエリの99%以上が単一のアプリケーションによって実行されますが、時間の経過とともにスクリプトが表示され始めます。スクリプトは必要に応じて手動で実行されるか、cronジョブです。一部のデータ操作も、データベース自体で手動で実行されます。スクリプトと手動のSQLクエリの両方で、無効な値が導入されるリスクが高くなります。

そして、私の質問が来ます:

チェック制約なしで、最終的には外部キーなしでリレーショナルデータベースをモデル化する理由は何ですか?


価値があることについては、この質問と私が受け取った回答(特にThomas Kilianとの興味深い議論)が データベースの制約に関する私の結論の記事 を書くきっかけになりました。

46

データベースのさまざまな使用例を区別することが重要です。

従来のビジネスデータベースは、複数の独立したアプリケーションとサービスによって、そしておそらく認可されたユーザーによって直接アクセスされます。データベースレベルで十分に検討されたスキーマと制約を持つことが重要です。そのため、単一のアプリケーションのバグや見落としによってデータベースが破損することはありません。データベースはビジネスに不可欠です。つまり、一貫性のないデータや破損したデータは、ビジネスに悲惨な結果をもたらす可能性があります。アプリケーションが出入りする間、データは永久に存続します。これらは、データベースの一貫性と正常性を確保するために専用のDBAがいる可能性がある場所です。

しかし、データベースが単一のアプリケーションと緊密に統合されているシステムもあります。スタンドアロンアプリケーションまたは単一の組み込みデータベースを備えたWebアプリケーション。データベースが単一のアプリケーションによって排他的にアクセスされている限り、アプリケーションが正しく機能している限り、制約を冗長と見なすことができます。これらのシステムは、アプリケーションコードに重点を置いて、おそらくリレーショナルモデルを深く理解していないプログラマーによって開発されることがよくあります。アプリケーションがORMを使用する場合、制約はアプリケーションプログラマにとってより馴染みのある形式でORMレベルで宣言されます。ローエンドにはPHP MySQLを使用するアプリケーションがあり、長い間MySQLは基本的な制約をまったくサポートしていなかったため、アプリケーション層に依存するhad一貫性を確保するため。

これらのさまざまなバックグラウンドを持つ開発者が出会うと、カルチャークラッシュが発生します。

このミックスには、分散型「クラウドストレージ」データベースの新しい波が訪れます。パフォーマンスの利点を失うことなく分散データベースの一貫性を保つことは非常に難しいため、これらのデータベースはデータベースレベルでの一貫性チェックを避け、プログラマーが基本的にアプリケーションレベルでそれを処理できるようにします。アプリケーションごとに一貫性の要件は異なります。Googleの検索エンジンは、サーバー全体の一貫性よりも可用性を優先しますが、私は、給与システムが多くの制約のあるリレーショナルデータベースで実行されることを望んでいます。

28
JacquesB

今日、ますます多くのシステムがクラウド上の分散環境で実行され、「スケールアップ」ではなく「スケールアウト」する手法を採用しています。 eコマースアプリなど、インターネットに直接接続するオンラインアプリケーションを扱う場合は、さらに重要です。

とはいえ、スケーリングすることになっているすべてのアプリケーションは CAP Theorem によって制約されます。ここで、2:3の整合性、可用性、およびパーティショントレランス(ネットワークフォールトトレランス)を選択する必要があります。

CAP定理を検討すると、選択肢があまりないことがわかりますが、ネットワークを100%信頼することはできないため、可用性または一貫性のいずれかを失うことを選択します。

一般に、いくつかのアプリケーションは、ある程度の時間にわたって不整合が生じる可能性がありますが、ユーザーが利用できないことは許されません。たとえば、FacebookまたはTwitterのタイムラインが少し順序付けられていない場合は、タイムラインにまったくアクセスできないよりも優れています。

したがって、リレーショナルデータベースは整合性は非常に優れていますが、可用性が犠牲になるため、いくつかのアプリケーションがリレーショナルデータベースの制約を取り除くことを選択しています。

個人的なメモ:私も昔ながらで、データの整合性がほとんどの場合ファーストクラスの要件であり、データベースの制約の大ファンであるいくつかの本当に古い金融システムで働いています。データベースの制約は、何年にもわたる悪質な開発と行き来する開発者のチームに対する最後の防御線です。

「Ebus modus in rebus」。一貫性が第一級の要件であるDB「低レベル」の一貫性を使い続けましょう。しかし、時には、それを手放すことは結局大きな罪ではありません。

-編集:-

質問には小さな編集が含まれているため、データベースの制約を削除する正当な理由として、IMOがあります。マルチデータベーステクノロジーをサポートするようにシステムを設計する製品を最初から設計する場合、サポートされているデータベースの中で最も一般的でない分母に妥協し、最終的にすべての制御ロジックを残して、すべての制約の使用をやめることができます。あなたの申請。

正当ではありますが、元の質問で提案されたような単純な制約をサポートしていないデータベースエンジンを今日見つけることができないため、私にとっては灰色の領域でもあります。

15
Machado

チェック制約なしで、最終的には外部キーなしでリレーショナルデータベースをモデル化する理由は何ですか?

最初に、私がここで話しているのはRDBMについてのみであり、SQL以外のデータベースについてではないことを明確にしましょう。

FKやPKのないデータベースをいくつか確認しました。制約をチェックすることは言うまでもありませんが、正直なところ、それらは少数派です。おそらく私は大企業で働いているからでしょう。

長年の経験から、いくつかの理由が考えられます。

  • 初心者または趣味プログラマの場合、l モデリングスキルの欠如
  • ORMの広範囲またはほぼ排他的な使用データベースの世界との実際の接触なし
  • DBAやその他のデータモデリングの不在チームまたは小規模プロジェクトの専門家
  • DBAまたはデータモデリングの関与の欠如開発の最初の段階の専門家
  • 慎重な設計決定特定の列が値として1,2 or 3しか持てないことを強制するチェック制約でさえ、または「年齢」列は必須であると考える開発者コミュニティの一部be >= 0 is "データベースにビジネスロジックがある"。このサイトの最近のいくつかの質問と回答でわかるように、デフォルトの句でさえ、一部はデータベースに属さないビジネスロジックと見なされます。このように考慮しているこの開発者は、明らかに最小限の制約を使用し、参照整合性や単一性さえも、コードですべてを行います。これは極端な立場だと思います。
  • キー値ストレージとしてのRDBMの使用、SQLなしの動作をエミュレートするため、またはRDBMSテーブルをキー値リポジトリとして使用することで要件を満たすのに十分単純であるため。
  • データベースは常に「アプリ」によって書き込まれると想定であり、大量のデータをロードしたり、SQLクライアントを介して行を編集または挿入したりする必要はありません(多くの場合、問題を修正するため)アプリが挿入したデータ)。最良の場合のシナリオでは、データベースにDML命令を発行する別のアプリ(「アプリ」以外)が常に存在します。SQLクライアントです。
  • アプリではなくデータはビジネスオーナーに属しますであることを認識していません。

そうは言っても、私はRDBMSは巨人の肩の上に構築された非常に高度なソフトウェアですであり、多くのビジネス要件に対して非常に効率的であり、平凡なタスクのプログラマーを解放します一連のバイナリファイルまたはテキストファイルに参照整合性を適用する方法。私がいつも言っているように"私たちはもはや1つのアプリから1つのデータベースの世界には住んでいません"。少なくともSQLクライアントは、「アプリ」のほかにDMLを発行します。したがって、データベースは、人的エラーまたはプログラミングエラーから妥当な範囲で防御する必要があります。

RDBMSが適切にスケーリングされないこれらのよく知られたタイプの要件では、必ずSQL以外のテクノロジーを採用するです。しかし、RDBMSがより効率的な方法で強制する必要があるものを強制するために何千行ものコード(生成または型付き)が費やされるという制約のない、リレーショナルデータベースの急増を心配しています。

10

テクノロジーの決定を左右する外部の制約があります。データベースフィールドの制約を定期的に使用する必要性や贅沢がある状況はほとんどありません。

  1. 企業にはDBAと共にアプリとデータベースの両方の開発者がいますが、ほとんどの開発者はこのタイプの環境では作業しません。彼らはコードでできる限りのことをします。また、データベース側の一部はビジネスルールに関与しません。彼らは主に物事を実行し続けるためにそこにあります。データベース内の制約をプッシュすることは決してありません。レガシーアプリ、統合、移行、合併、買収に対処することは、db制約が最善の解決策になる場合があります。
  2. Dbをオーバーロードすると、ボトルネックが発生する可能性がありますが、問題により多くのマシンを投入するだけでは簡単に解決できません。パフォーマンスに大きな影響を与えずにdb言語でプログラミングの問題を処理できない状況があるため、すべてに制約を使用することはできません。問題に2を投げるのは難しいので、Stackoverflowには1つのデータベースサーバーがあります。
  3. 自動テスト-彼らはそこに着いていますが、多くのデータベース開発者はIDE /テストフレームワークと共にパーティーに遅れています。
  4. 配備-より多くのdbのものはそれをより複雑にします。制約に違反するデータがあるためにクライアントのデータベースの更新が許可されない場合はどうなりますか?これに対処する方法がない限り、ゲームオーバー。アプリでは、必要に応じてユーザーがこれを処理できるようにするか、一部の管理者にバッチで実行するように指示することができます。
  5. App/api/serviceのみがデータベースにデータを書き込むので、なぜわざわざ?これはほとんどの時間を保持します、それはそれが一般的でない理由です。
  6. データベースエラーの処理は、何百もの制約違反がなければ、何もかもがハックから外れた場合に対処するのに十分なほど困難です。

多くの開発チームは、db開発者にあまり多くの制御を与えたくありません。 1つ以上ゲットできたらラッキーなので、休暇はとても楽しいです。多くの場合、データベースドメインを完全に制御する必要はなく、すべてのクエリ、ビジネスルール、パフォーマンス、可用性、セキュリティ、およびどのデータがどのRAIDに送信されるかについて責任を負います。実行を許可されているストアドプロシージャは次のとおりです。楽しんで。テーブルに触れることさえ考えないでください。

3
JeffO

これは、私のキャリア(40年近く)と、DBMSを作成するときに苦労してきた問題です。私のエンドポイントの説明はここにあります: http://unibase.zenucom.com 。だからここに私の考えがあります。

  1. 一般的に言えば、ほとんどの制約はアプリケーションでより適切に処理されるため、アプリケーションのさまざまな部分がさまざまな制約を適用できます。たとえば、州法はすべての管轄区域に適用されるわけではありません。
  2. 余談ですが%に注意してください。マークアップが> 100%であるか、破られました:)
  3. 制約は否定的に最もよく説明されます。つまり、彼らがあり得ないものであって、本来あるべきものではない。常によりシンプルなリストです。
  4. 外部キーは常に適切であり、使用する必要があります。フルストップ。 FKはRDBMSの数少ない意味構造の1つであり、非常に便利です。最大の問題は、FKが削除された場合に値をぶら下げるか、またはFKレコードを削除しない理由として従属行を使用するかを決定することです。
  5. 現実の世界の制約は、通常、単一のフィールド値の制約よりも複雑です。
  6. 一部の制約は、アプリケーションレベルでも、適切な操作に反します。たとえば、積極的な日付チェックは、明らかに良い日付のエラーを隠します。そうでなければ賢明に見える日付のエラーの測定値を取得するには、オペレーターのエラーが必要です。
2
Rick Marshall

最近では、人々はソフトウェア(Entity Frameworkなど)を使用してテーブルと列を自動的に生成しています。彼らはSQLスキルを必要とせず、脳の能力を解放するという考えです。

ソフトウェアが「うまくいく」という期待は、しばしば非現実的であり、人間がするような制約を生み出すものではありません。

最良の結果を得るには、SQLを使用してテーブルを作成し、制約を手動で追加しますが、これができない場合もあります。

1
user147272

データベースの制約は賢明なアイデアだったかもしれませんが、それらの実用的な使用についてはどうでしょうか?パーセンテージ制約を考慮してください。これを適用すると、DBは無効なパーセンテージを喜んで拒否します。その後?例外を処理するにはビジネスロジックが必要です。これは実際には、間違ったパーセンテージを書き込むビジネスロジックがすでに他の場所で失敗していることを意味します。要するに、残っている唯一の実用的な制約は(PK/FKのような)目に見えるものです。

1
qwerty_so