データベースに制約を加えることをためらわないでください。一貫性のあるデータベースが確実に得られます。これがデータベースを使用する理由の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 UPDATE RESTRICT:デフォルト:テーブルCOMPANYのcompany_idを更新しようとすると、1人のユーザーが少なくともこの会社にリンクしている場合、エンジンは操作を拒否します。
- 更新時のアクションなし:RESTRICTと同じです。
- ON UPDATE CASCADE:通常は最良のものです。COMPANYテーブルの行でcompany_idを更新すると、エンジンはこのCOMPANYを参照するすべてのUSER行でそれに応じて更新します(ただし、USERテーブルでトリガーがアクティブになっていません、警告)。エンジンが変更を追跡します。
- ON UPDATE SET NULL:テーブルCOMPANYの行でcompany_idを更新すると、エンジンは関連するユーザーのcompany_idをNULLに設定します(USER company_idフィールドで使用できる必要があります)。アップデートでそれと関係のある面白いことは見当たらないが、私は間違っているかもしれない。
そしてON DELETE側で:
- ON DELETE RESTRICT:デフォルト:テーブルCOMPANYのcompany_id Idを削除しようとすると、1人のユーザーが少なくともこの会社にリンクしている場合、エンジンは操作を拒否し、命を救うことができます。
- 削除しない場合:RESTRICTと同じ
- ON DELETE CASCADE:危険:テーブルCOMPANYの会社行を削除すると、エンジンは関連するユーザーも削除します。これは危険ですが、セカンダリテーブルを自動的にクリーンアップするために使用できます(したがって、それはあなたが望むものになる可能性がありますが、COMPANY <-> USERの例ではまったくありません)
- ON DELETE SET NULL:一握り:COMPANY行を削除すると、関連するUSERは自動的にNULLとの関係を持ちます。会社を持たないユーザーにとってNullがあなたの価値である場合、これは良い振る舞いである可能性があります。たとえば、一部のコンテンツの作成者としてユーザーをアプリケーションに保持する必要があるかもしれませんが、会社を削除することはあなたにとって問題ではありません。
通常、私のデフォルトはON DELETE RESTRICT ON UPDATE CASCADEです。いくつかON DELETE CASCADE
のトラックテーブル(ログ-すべてのログではない-など)を使用ON DELETE SET NULL
し、マスターテーブルがUSERテーブルのJOBテーブルのような外部キーを含むテーブルの「単純な属性」である場合。
編集する
私が書いてから久しぶりです。ここで、重要な警告を1つ追加する必要があると思います。MySQLには、カスケードに関する1つの大きな文書化された制限があります。カスケードはトリガーを起動していません。そのため、そのエンジンでトリガーを使用するのに十分な自信がある場合は、カスケード制約を避けてください。
MySQLトリガーは、SQLステートメントによってテーブルに加えられた変更に対してのみアクティブになります。ビューの変更や、SQLステートメントをMySQLサーバーに送信しないAPIによって行われたテーブルの変更によってアクティブ化されません。
==>最後の編集の下を参照してください、物事はこのドメインで動いています
トリガーは、外部キーアクションによってアクティブ化されません。
そして、これはいつか修正されるとは思いません。外部キー制約はInnoDbストレージによって管理され、トリガーはMySQL SQLエンジンによって管理されます。両方が分離されています。Innodbは、制約管理を備えた唯一のストレージです。おそらく、ストレージエンジンに直接トリガーを追加するかもしれませんが、そうしないかもしれません。
しかし、私はあなたが貧弱なトリガー実装と非常に有用な外部キー制約サポートの間で選択すべき要素について私自身の意見を持っています。そして、データベースの整合性に慣れると、PostgreSQLが気に入るはずです。
2017年12月-MySQLに関するこの編集の更新:
コメントで@IstiaqueAhmedが述べたように、この件に関して状況は変わりました。したがって、リンクをたどって、実際の最新の状況をチェックしてください(将来は再び変更される可能性があります)。
ON DELETE CASCADE : dangerous
-ひとつまみの塩で服用してください。