sql >> データベース >  >> RDS >> Mysql

外部キーの制約:ONUPDATEおよびONDELETEを使用する場合

    データベースに制約を課すことを躊躇しないでください。一貫性のあるデータベースが確実に作成されます。これが、データベースを使用する理由の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;
    

    更新中を見てみましょう 条項:

    • 更新制限についてデフォルト :テーブルCOMPANYのcompany_idを更新しようとすると、少なくとも1人のユーザーがこの会社にリンクしている場合、エンジンは操作を拒否します。
    • 更新時のアクションなし :RESTRICTと同じ。
    • 更新カスケード通常は最高のもの :テーブルCOMPANYの行でcompany_idを更新すると、エンジンはこのCOMPANYを参照するすべてのUSER行でそれに応じて更新します(ただし、USERテーブルでトリガーはアクティブ化されません。警告)。エンジンが変更を追跡します。これは良いことです。
    • ON UPDATE SET NULL :テーブルCOMPANYの行のcompany_idを更新すると、エンジンは関連するUSERのcompany_idをNULLに設定します(USER company_idフィールドで使用可能である必要があります)。アップデートではそれと関係のある面白いことはわかりませんが、間違っている可能性があります。

    そして今、削除中 サイド:

    • 制限を削除するデフォルト :テーブルCOMPANYのcompany_id Idを削除しようとすると、1人のユーザーが少なくともこの会社にリンクしている場合、エンジンは操作を拒否し、あなたの命を救うことができます。
    • アクションを削除しないでください :RESTRICTと同じ
    • カスケードの削除時危険 :テーブルCOMPANYの会社行を削除すると、エンジンは関連するUSERも削除します。これは危険ですが、セカンダリテーブルの自動クリーンアップを作成するために使用できます(したがって、必要なものにすることができますが、COMPANY <-> USERの例では絶対にそうではありません)
    • ON DELETE SET NULL 一握り :COMPANY行を削除すると、関連するUSERは自動的にNULLとの関係になります。 Nullが会社を持たないユーザーにとっての価値である場合、これは良い動作になる可能性があります。たとえば、一部のコンテンツの作成者としてユーザーをアプリケーションに保持する必要があるかもしれませんが、会社を削除することは問題ではありません。
    • >

    通常、私のデフォルトは次のとおりです。更新カスケードで制限を削除する 。いくつかのON DELETE CASCADE トラックテーブル(ログ-すべてのログではない-、そのようなもの)およびON DELETE SET NULL マスターテーブルが、USERテーブルのJOBテーブルのように、外部キーを含むテーブルの「単純な属性」である場合。

    編集

    それを書いてから久しぶりです。ここで、重要な警告を1つ追加する必要があると思います。 MySQLには、カスケードに関する1つの大きな文書化された制限があります。 カスケードはトリガーを起動していません 。したがって、トリガーを使用するのに十分な自信がそのエンジンにある場合は、カスケードの制約を回避する必要があります。

    ==>最後の編集の下を参照してください。このドメインで物事が進んでいます

    そして、私はこれがいつか修正されるとは思わない。外部キー制約はInnoDbストレージによって管理され、トリガーはMySQLSQLエンジンによって管理されます。両方が分離されています。 Innodbは、制約管理を備えた唯一のストレージです。おそらく、いつかストレージエンジンに直接トリガーを追加するかもしれませんが、そうではないかもしれません。

    しかし、不十分なトリガーの実装と非常に便利な外部キー制約のサポートのどちらを選択する必要があるかについては、私自身の意見があります。そして、データベースの一貫性に慣れれば、PostgreSQLを気に入るはずです。

    2017年12月-MySQLに関するこの編集の更新:

    コメントで@IstiaqueAhmedが述べているように、この件に関して状況は変化しました。そのため、リンクをたどって、実際の最新の状況を確認してください(将来、再び変更される可能性があります)。



    1. Linuxで実行されているアプリケーションをSQLServerのAmazonRelationalDatabase Services(RDS)に接続する

    2. MySQLのTIMEDIFF()とSUBTIME():違いは何ですか?

    3. PHP/MySQLでのファイルのダウンロード時間

    4. MySQLに書き込むときにTextAreaからの改行を保持する