22


6

私は外部キーであるテーブルにカラムを作成しようとしていますが、MySQLではそれがあるべきよりも難しいです。 それは私が戻って、すでに使用中のテーブルに特定の変更を加えることを要求するでしょう。 ですから、MySQLが特定の値が適切であることを確認することはどの程度必要なのでしょうか。 私はこのデータベースにアクセスするために使用しているPHPのような言語でそれを実行できないでしょうか。

NOT NULLも同様です。 このデータベースにPHPのみでアクセスする場合、単にnull値が入力されていないことをPHPに確認させることはできませんか。

PHPだけでできるのに、なぜこれらの制約を強制するためにMySQLを使うべきなのか?*

'' '' '

私は、NOT NULLは上記の理由で無視するのが非常に愚かな部分であることを認識しています。 しかし、MySQLは深刻な度合いの煩わしさなしには外部キーを強制しません。

あなたの意見では、「偽の」外部キーを使用して、入力された値が他のテーブルと一致するかどうかをPHPで確認することは依然として悪いことでしょうか。

15 Answer


55


あなたは100%保証された、PHPとの間違いを犯すことを_進行中です。 PHPは手続き型です。 欲しいのは宣言的な制約です。 スタック全体を見てみましょう。「これらはデータに対する制約であり、これらの制約に違反することはできません。」 "Step 1 …​"についてはあまり考えたくありません。 ステップ2 …​ ステップ3 ステップ432 …​ "、データに制約を強制する方法として

  • あなたはそれを悪くするつもりです

  • 後で変更すると、今行ったことを忘れてしまいます

  • あなたが今それらを知っているように、他の誰もこれらの暗黙の制約の全てを知ることはないでしょう

  • データベースサーバーはすでにこのコードを持っていますが、あなたはそれを書く用意ができていますか?

質問は実際には疑問に思うべきです、「MySQLでそれをやることができるのに、なぜこれらの制約を強制するためにPHPを使うべきなのか」。


17


プログラマーが「ただ」バグのないコードを書くことができないのと同じ理由で、あなたは「ただ」「 PHPでそれをすることはできません。 あなたが思うより難しいです。 特にそれほど難しいことではないと思うのであれば。


8


他の方法でDBにアクセスすることは絶対にできないというあなたの人生を誓うことができるなら、あなたの(もちろんバグのない)PHPページ以外はPHP単独でそれをすることは大丈夫でしょう。

実社会のシナリオには常に不確実性があるため、DBサーバーにデータの整合性を監視させるのが得策です。

単純なデータベースでは、参照整合性制約は絶対的な要件ではないかもしれませんが、持っておくといいでしょう。 アプリケーションが複雑になればなるほど、それらからより多くの利益を引き出すことができます。 早めに計画することで、後であなたの人生が楽になります。

さらに、参照整合性は、すべてのダーティーハックが可能であるとは限らないため、データベースをより手際の良い方法で設計することを強制するのに役立ちます。 これも良いことです。


2


それらは非常に重要です。 あなたは完全にPHPを通してあなたのモデルを定義したくありません。 PHPコードにバグがあるとどうなりますか? あなたのビジネスルールがあなたがそうすべきではないと述べるところでは、あなたは簡単にnull化されたカラムを持つことができます。 データベースレベルで定義することで、少なくともそのチェックを無料で受けることができます。 あなたのPHPにバグがあるとき、あるいは他のツールがあなたのデータベースを使っているとき、あなたはそれを本当に嫌うでしょう。 あなたはただ問題を求めているのです、私見。

注意してください、これは物語の非常に短いバージョンです。


2


将来を予測することは不可能であるため、データベースに制約を実装することが重要です。 あなたはあなたの要求がいつ変わるのかを決して知りません。

また、同じアプリケーションで複数の開発者が作業している可能性もあります。 あなたはすべての制約が何かを知っているかもしれませんが、ジュニア開発者はそうではないかもしれません。 データベースに制約があると、ジュニア開発者のコ​​ードはエラーを生成し、彼は何かを修正する必要があることを知るでしょう。 制約がなければ、コードは失敗せず、データが破損する可能性があります。


2


私は通常、データベース内で制約を宣言することに賛成です。 制約のための引数:

  • 宣言型コードは、命令型コードよりもバグが発生しにくくなります。 アプリコードにバグが含まれていても、制約が適用されます。

  • 複数のアプリケーションまたはコードモジュールが同じデータベースにアクセスしていて、ビジネスルールを統一して実施する必要がある場合は、「自分自身を繰り返さない」という原則をサポートします。 制約を変更する必要がある場合は、多くのアプリがある場合でも、1か所で変更できます。

  • ユーザーがアプリケーションを迂回しようとした場合でも、データの整合性を強化します。アドホッククエリツールを使用してデータベースを調整します。

  • _consistency_を強制します。これは、データ更新の前後に常にデータが有効な状態にあることを確認できることを意味します。 制約を使用しない場合は、定期的なクエリを実行して破損した参照を確認し、それらをクリーンアップする必要があります。

  • カスケード更新/削除を制約付きで簡単にモデル化できます。 アプリケーションコードで同じことをするのは複雑で効率が悪く、変更をアトミックに適用することはできません(トランザクション分離を使用することをお勧めします)、そしてバグの影響を受けやすいです。

  • 列名とSQLデータ型が役立つのと同様に、制約はデータベースの自己文書化を支援します。

制約に対する引数

  • より複雑なビジネスルールは宣言型の制約ではモデル化できないため、とにかくアプリケーションスペースに実装する必要があります。 それでは、すべてのビジネスルールを1か所(アプリ)と同じ言語で実装しないでください。 これにより、コードリビジョンのデバッグ、テスト、追跡が容易になります。

  • 制約には索引が含まれることが多く、挿入/更新中にある程度のオーバーヘッドが発生します。 一方、制約を宣言しなくても、列が検索条件や結合条件で頻繁に使用される可能性があるため、とにかくインデックスが必要になるでしょう。

  • 制約があると、データの間違いを「片付ける」という試みが複雑になる可能性があります。

  • 現在のプロジェクトでは、MyISAMと非互換性 参照制約に関してInnoDBはいくらかの悲しみを引き起こしています。


1


NOT NULLを使用する上で最も重要なことは、ドキュメントの部分です。 数ヵ月後にプロジェクトに戻ると、どの列にNULLを入れることが許容されるかを忘れています。 列にNOT NULLと表示されている場合は、その列に含まれる潜在的なNULL値を処理する必要はまったくないことを私は知っています。 そしてそれがnullを許すならば、私は彼らに対処しなければならないことを私は確かに知っています。

他の人が指摘したように、他のことは、あなたがどこかに何かを見逃していて、データをクリーンアップしているか、または全く不可能であるかもしれないということです。 データベース内のすべてのデータに一貫性があることを確認することをお勧めします。


1


MySQLでこれらの制約を有効にすると、ほぼゼロの時間で済みます。 欠陥のあるPHPや他のコードによる単一のバグからでもあなたを救えば、それだけの価値はありませんか?

あなたがあなた自身を救うであろう種類のバグはかなり厄介でありえることを心に留めておいてください。 バグ自体を見つけて修正するのは難しいことではありません。厄介なのは、バグを修正すると、修復不可能な場合もある一連の誤ったデータが残ることです。

私はこの問題に「PHP以外のものがいつかあなたのデータにアクセスするかもしれない」という角度からアプローチすることすらありません。 それは本当です、しかし私の心の中でさらに重要なのは、頭痛、時間(お金)、そしてデータ損失です。それはあなたが簡単な制約をいくつか追加することによってあなた自身を救うことができます。


1


データベースを構造データの整合性に使用し、残りの部分にはBR層を使用します。 そして、できるだけ早くエラーを見つけます。 彼らは一緒に働きます。

運が良ければ、コードが完成した時点でデータベースのRIエラーが発生することはありません。そしてあなたは誇らしげに自分自身が最初になるように発表することができます。


1


データ層に制約を介してデータの一貫性を強制することで、データの一貫性を維持し、アプリケーション内で安価な実行時のバグチェックを実現できます。

制約が価値がないと考えるのなら、あなたは小規模/非ミッションクリティカルなシステムを持っているか、あなたのシステムの品質を改善するために*巨大な*機会を譲っています。 これは控えめに言うことはできません。

選択肢は次のとおりです。別のRDBMSを選択する、独自のメタデータシステムを再発明する、または手動で制約を管理する。 メタデータシステムを使用しないクエリでの手動管理は、スキーマ/システムの複雑さが増し、進化し続けるスキーマを不必要に複雑にするため、適切に保守および監査することがすぐに不可能になります。

私のお勧めは、違うRDBMSを選ぶことです。

一貫性チェックはあなたが考えるよりもずっと難しいです。 たとえば、MySQLはトランザクション読み取り一貫性を使用します。これは、チェックしている値が別のトランザクションの範囲内で同じ値ではない可能性があることを意味します。 同時アクセスのための一貫性の方法論は、データ層に直接縛られていないと正しく理解するのが非常に困難です。

手作業による検査に多少の労力を費やしても、すべてを言って完了すると、考えられなかった、または成形時のエラーを犯したコーナーケースを通して、トラックを運転できる可能性があります。

NOT NULLの質問について 明らかなデータフィールドの要件は良い出発点です。 列のNULL可能性を定義する際に考慮すべき他の点がいくつかあります。

それは、クエリを書くときにとても役立つ保証を提供します。 さまざまな結合でNULL条件を使用して、条件がNULLを許可する場合に想定できないNULL値とは別に表の行の不一致を示すことができます。 (NULLが許可されている場合、一致は、行が一致しなかったか、行は一致したが列の値がNULLであることを意味します。)

NOT NULLを使用すると、値が一致する単純なクエリの規則を定義するのにも役立ちます。 value1とvalue2の両方がNULLの場合、 "WHEN value1 = value2"とは言えないので、評価の結果は依然として偽です。