私はMySQL Workbenchを使用してデータベーススキーマを設計していますが、これはダイアグラムを作成して変換できるため、かなりクールです:P
とにかく、InnoDBを使用することにしました。これは、外部キーのサポートのためです。私が気づいたことの1つは、外部キーの更新時および削除時のオプションを設定できることです。誰かが簡単な例で「制限」、「カスケード」、およびnullを設定できる場所を説明できますか?
たとえば、user
を含むuserID
テーブルがあるとします。そして、2つの外部キー(同じ主キー、message
テーブルのuserID
を参照する)を持つ多対多のメッセージテーブルuser
があるとします。この場合、[更新時]および[削除時]オプションの設定は役に立ちますか?その場合、どれを選択しますか?これが良い例ではない場合、これらがどのように役立つかを説明するための良い例を考えてください。
ありがとう
データベースに制約を加えることをheしないでください。一貫性のあるデータベースが必ず得られますが、それがデータベースを使用する良い理由の1つです。特に、複数のアプリケーションがそれを要求している場合(または、1つのアプリケーションだけで、異なるソースを使用するダイレクトモードとバッチモードがある場合)。
MySQLでは、postgreSQLのような高度な制約はありませんが、少なくとも外部キー制約は非常に高度です。
例として、これらの会社の人を含むユーザーテーブルを持つ会社テーブルを取り上げます。
CREATE TABLE COMPANY (
company_id INT NOT NULL,
company_name VARCHAR(50),
PRIMARY KEY (company_id)
) ENGINE=INNODB;
CREATE TABLE USER (
user_id INT,
user_name VARCHAR(50),
company_id INT,
INDEX company_id_idx (company_id),
FOREIGN KEY (company_id) REFERENCES COMPANY (company_id) ON...
) ENGINE=INNODB;
ON UPDATE句を見てみましょう:
そして今、ON DELETE側:
通常、デフォルトはON DELETE RESTRICT ON UPDATE CASCADEです。いくつかのON DELETE CASCADE
をトラックテーブル(すべてのログではなく、ログなど)に使用し、マスターテーブルがUSERテーブルのJOBテーブルのような外部キーを含むテーブルの「単純な属性」の場合にON DELETE SET NULL
を使用します。
編集
それを書いてから久しぶりです。ここで、重要な警告を1つ追加する必要があります。 MySQLには、カスケードに関する1つの大きな文書化された制限があります。 カスケードはトリガーを起動していません。そのため、そのエンジンでトリガーを使用するのに十分自信がある場合は、カスケード制約を回避する必要があります。
MySQLトリガーは、SQLステートメントによってテーブルに加えられた変更に対してのみアクティブになります。ビューの変更や、SQLステートメントをMySQLサーバーに送信しないAPIによって行われたテーブルの変更に対してはアクティブになりません。
==>以下の最後の編集を参照してください、物事はこのドメインで動いています
トリガーは、外部キーアクションによってアクティブ化されません。
そして、私はこれがいつか修正されるとは思わない。外部キー制約はInnoDbストレージによって管理され、トリガーはMySQL SQLエンジンによって管理されます。両方が分離されています。 Innodbは制約管理を備えた唯一のストレージです。たぶん、いつかストレージエンジンに直接トリガーを追加するかもしれません。
しかし、貧弱なトリガー実装と非常に有用な外部キー制約サポートのどちらを選択すべきかについて、私は自分の意見を持っています。そして、データベースの一貫性に慣れると、PostgreSQLが好きになります。
@IstiaqueAhmedがコメントで述べたように、この主題の状況は変わりました。そのため、リンクをたどって、実際の最新の状況を確認してください(将来、再び変わる可能性があります)。
@MarkR回答への追加-注意すべきことの1つは、ORMを使用する多くのPHPフレームワークが高度なDBセットアップ(外部キー、カスケード削除、一意制約)を認識または使用しないため、予期しない動作が発生する可能性があることです。
たとえば、ORMを使用してレコードを削除し、DELETE CASCADE
が関連テーブルのレコードを削除する場合、ORMがこれらの関連レコードを削除しようとすると(多くの場合自動)エラーが発生します。
これは、アプリケーションのコンテキストで考慮する必要があります。一般に、データベースではなくアプリケーションを設計する必要があります(データベースは単にアプリケーションの一部です)。
アプリケーションがさまざまなケースにどのように応答するかを検討してください。
デフォルトのアクションは、操作を制限する(許可しない)ことです。これは通常、愚かなプログラミングエラーを防ぐために必要な操作です。ただし、DELETEではCASCADEも役立ちます。それは実際にアプリケーションと特定のオブジェクトを削除する方法に依存します。
個人的に、InnoDBを使用するのは、FK制約があるためというよりも、データを破壊しないためです(MyISAMを破壊します)。