InnoDB
        は外部キー制約をサポートします。InnoDB
        内の外部キー制約定義の構文は次のようになります:
      
[CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name, ...) REFERENCEStbl_name(index_col_name,...) [ON DELETEreference_option] [ON UPDATEreference_option]reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION
        index_name は外部キーの ID
        を表します。これを指定しても、外部キーのインデックスが明示的に定義された場合にはこれは無視されます。それ以外の場合、InnoDB
        は外部キーのインデックスを作成する場合に、index_name
        をインデックス名として使用します。
      
外部キー定義には次のような条件があります:
            両方のテーブルは
            InnoDB
            テーブルである必要があり、それらは
            TEMPORARY
            テーブルではいけません。
          
            型変換をせずに比較できるよう、外部キーと参照キー内の対応するカラムは
            InnoDB
            内に類似内部データ型を持つ必要があります。整数型のサイズとサインは同じである必要があります。文字列型の長さは同じである必要はありません。非バイナリ列
            (文字列)
            の場合、キャラクタセットと照合が同一である必要があります。
          
            InnoDB
            は、外部キーチェックが速くなり、テーブル走査を必要としないよう、外部キーと参照キー上にインデックスを要求します。参照表の中では、外部キーカラムが同じ順番で
            first
            カラムとしてリストされているインデックスが存在する必要があります。もしそのようなインデックスが無ければ、自動的に参照表上に作成されます。(これは、いくつかの古いバージョン内での、インデックスが明示的に作成される必要があり、そうでなければ外部キー制約の作成が失敗する、というものとは対照的です。)
            index_name
            を指定した場合、その名前は前述のように使用されます。
          
            InnoDB
            では、外部キーは任意のインデックスカラムやカラムグループを参照できます。ただし、参照表の中では、参照カラムが同じ順番で
            first
            カラムとしてリストされているインデックスが存在する必要があります。
          
            外部キーカラム上のインデックス接頭辞はサポートされていません。この
            1
            つの結論は、それらのカラム上のインデックスは常に接頭辞長を含む必要があるため、BLOB
            と TEXT
            カラムを外部キー内に含むことができないということです。
          
            もし CONSTRAINT
            
            節が与えられると、symbolsymbol
            値はデータベース上で固有である必要があります。もし節が与えられなければ、InnoDB
            は名前を自動的に作成します。
          
        もし親テーブル内に適合する候補キー値が無ければ、InnoDB
        は子テーブル内に外部キー値を作成しようとする
        INSERT か
        UPDATE
        操作を拒絶します。子テーブル内にいくつかの適合する行を持つ親テーブル内で、候補キー値を更新または削除しようとする
        UPDATE や
        DELETE
        操作に対して
        InnoDB
        が取るアクションは、FOREIGN
        KEY 節の ON
        UPDATE と ON
        DELETE サブ節を利用して指定された
        referential action
        上で依存しています。ユーザーが親テーブルから行を削除または更新しようとして、子テーブル内に
        1
        つ以上の適合する行があるとき、InnoDB
        は取るべきアクションを考慮して 5
        つのオプションをサポートします.
        ON DELETE または
        ON UPDATE
        が指定されていない場合のデフォルトのアクションは、RESTRICT
        になります。
      
            CASCADE:親テーブルから行を削除または更新し、子テーブル内で自動的に適合行を削除または更新します。ON
            DELETE CASCADE と ON
            UPDATE CASCADE
            の両方がサポートされています。2
            つのテーブルの間で、親テーブル内、または子テーブル内で同じカラム上に機能するいくつかの
            ON UPDATE CASCADE
            節を定義するべきではありません。
          
現時点では、カスケード外部キーアクションがトリガーを有効にしません。
            SET
            NULL:親テーブルから行を削除または更新し、子テーブル内で外部キーカラムを
            NULL
            に設定します。これは外部キーカラムが指定された
            NOT NULL
            修飾子を持たないときだけ有効です。ON
            DELETE SET NULL と ON
            UPDATE SET NULL
            節の両方がサポートされています。
          
            SETNULL
            アクションを指定した場合、テーブル内のカラムを
            NOTNULL
            として宣言していないことを確認してください。
          
            NO
            ACTION:スタンダード SQL
            内で、NO ACTION
            は、もし参照表内に関連する外部キーがあれば主キー値を削除または更新しようとすることは許容されていないという意味で、no
            action
            を意味します。InnoDB
            は親テーブルの削除または更新操作を拒否します。
          
            RESTRICT:親テーブルの削除または更新操作を拒否します。RESTRICT
            (または NO ACTION)
            を指定することは、ON
            DELETE または ON
            UPDATE
            節を省略することと同じです。(いくつかのデータベースシステムが据え置き確認を持ち、NO
            ACTION が据え置き確認です。MySQL
            では外部キー制約の確認は即座に行われるため、NO
            ACTION は
            RESTRICT
            と同じになります。)
          
            SET
            DEFAULT:このアクションはパーサーによって認識されますが、InnoDB
            は ON DELETE SET DEFAULT
            か ON UPDATE SET DEFAULT
            節を含むテーブル定義を拒否します。
          
        InnoDB
        はテーブル内での外部キー参照をサポートします。これらのような場合、「子テーブルレコード」
        は本当に同じテーブル内で依存レコードを参照します。
      
        ここに、単一カラム外部キーを通して
        parent と
        child
        テーブルを関連させるシンプルな例があります:
      
CREATE TABLE parent (id INT NOT NULL,
                     PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (id INT, parent_id INT,
                    INDEX par_ind (parent_id),
                    FOREIGN KEY (parent_id) REFERENCES parent(id)
                      ON DELETE CASCADE
) ENGINE=INNODB;
        product_order
        テーブルが別の 2
        つのテーブルに外部キーを持つ、さらに複雑な例。1
        つの外部キーが product
        テーブル内の 2
        段インデックスに参照をつけます。その他のものは
        customer
        テーブル内で単一カラムインデックスに参照をつけます:
      
CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
                      price DECIMAL,
                      PRIMARY KEY(category, id)) ENGINE=INNODB;
CREATE TABLE customer (id INT NOT NULL,
                       PRIMARY KEY (id)) ENGINE=INNODB;
CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
                            product_category INT NOT NULL,
                            product_id INT NOT NULL,
                            customer_id INT NOT NULL,
                            PRIMARY KEY(no),
                            INDEX (product_category, product_id),
                            FOREIGN KEY (product_category, product_id)
                              REFERENCES product(category, id)
                              ON UPDATE CASCADE ON DELETE RESTRICT,
                            INDEX (customer_id),
                            FOREIGN KEY (customer_id)
                              REFERENCES customer(id)) ENGINE=INNODB;
        InnoDB は
        ALTER TABLE
        を利用してテーブルに新しい外部キー制約を追加することを許容します:
      
ALTER TABLEtbl_nameADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name, ...) REFERENCEStbl_name(index_col_name,...) [ON DELETEreference_option] [ON UPDATEreference_option]
        外部キーは、自己参照型にする
        (同じテーブルを参照する)
        ことができます。ALTER
        TABLE
        を使って外部キー制約をテーブルに追加する場合には、まず必要なインデックスを忘れずに作成してください。
      
        InnoDB
        は外部キーを削除するための
        ALTER TABLE
        の利用をサポートします。
      
ALTER TABLEtbl_nameDROP FOREIGN KEYfk_symbol;
        もし外部キーを作成したときに
        FOREIGN KEY 節が
        CONSTRAINT
        名を含んでいたら、外部キーを削除するためにその名前を参照することができます。そうでなければ、fk_symbol
        値は外部キーが作成されたときに
        InnoDB
        によって内部的に生成されます。外部キーを削除したいときにシンボル値を見つけるには、SHOW
        CREATE TABLE
        ステートメントを利用してください。例 :
      
mysql>SHOW CREATE TABLE ibtest11c\G*************************** 1. row *************************** Table: ibtest11c Create Table: CREATE TABLE `ibtest11c` ( `A` int(11) NOT NULL auto_increment, `D` int(11) NOT NULL default '0', `B` varchar(200) NOT NULL default '', `C` varchar(175) default NULL, PRIMARY KEY (`A`,`D`,`B`), KEY `B` (`B`,`C`), KEY `C` (`C`), CONSTRAINT `0_38775` FOREIGN KEY (`A`, `D`) REFERENCES `ibtest11a` (`A`, `D`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `0_38776` FOREIGN KEY (`B`, `C`) REFERENCES `ibtest11a` (`B`, `C`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=INNODB CHARSET=latin1 1 row in set (0.01 sec) mysql>ALTER TABLE ibtest11c DROP FOREIGN KEY `0_38775`;
        単一 ALTER
        TABLE
        ステートメントの別々の節の中に外部キーを追加したり削除したりはできません。別々のステートメントが要求されます。
      
        InnoDB テーブルの
        ALTER TABLE
        を実行した結果、カラムの切り詰めなどの理由によりカラムの値が変更されても、InnoDB
        の FOREIGN KEY
        制約チェックはその値の変更によって発生した可能性のある違反を通知しません。
      
        InnoDB
        パーサーは、FOREIGN KEY ...
        REFERENCES ...
        節内のテーブルとカラム識別子が逆引用符内で参照されることを許容します。(あるいは、もし
        ANSI_QUOTES
        SQL
        モードが有効であれば二重引用符を利用することもできます)。InnoDB
        パーサーは、lower_case_table_names
        システム変数の設定も考慮します。
      
        InnoDB
        はテーブルの外部キー定義を
        SHOW CREATE TABLE
        ステートメントの出力の一部として返します:
      
SHOW CREATE TABLE tbl_name;
mysqldump はテーブルの正しい定義もダンプファイル内に作成し、外部キーのことも忘れません。
次のようにテーブルの外部キー制約を表示することもできます:
SHOW TABLE STATUS FROMdb_nameLIKE 'tbl_name';
        外部キー制約は出力の
        Comment
        カラム内にリストされています。
      
        外部キーチェックを行っているとき、InnoDB
        はそれが見なければいけない子または親レコード上に共有行レベルロックを設定します。InnoDB
        は外部キー制約の確認を即座に行います。その確認がトランザクションコミットまで遅延されることはありません。
      
        外部キー関係を持つテーブルのダンプファイルの再ロードを簡単にするために、mysqldump
        は
        foreign_key_checks
        を 0
        に設定するために自動的にダンプ出力内にステートメントを含みます。これは、ダンプが再ロードされたときにテーブルが特定の順番で再ロードされなければいけないという問題を防ぎます。この変数をマニュアルで設定することも可能です:
      
mysql>SET foreign_key_checks = 0;mysql>SOURCEmysql>dump_file_name;SET foreign_key_checks = 1;
        これは、もしダンプファイルが外部キーに対して正しい順番でオーダされていないテーブルを含んでいたら、テーブルをどんな順番でインポートしてもよいと許容します。これはインポート操作のスピードも上げます。foreign_key_checks
        を 0
        に設定することは、LOAD
        DATA と ALTER
        TABLE
        操作の最中に外部キー制約を無視するためにも役に立ちます。しかし、foreign_key_checks
        = 0 であったとしても、InnoDB
        は、カラムが非適合カラム型の参照をつける外部キー制約の作成を許容しません。また、外部キー制約を含む
        InnoDB
        テーブルでは、ALTER
        TABLE
        を使ってそのテーブルが別のストレージエンジンを使用するように変更することはできません。ストレージエンジンを変更するには、まずすべての外部キー制約を削除する必要があります。
      
        InnoDB
        は、SET foreign_key_checks =
        0
        を行わないかぎり、FOREIGNKEY
        制約から参照されているテーブルを削除することを許容しません。テーブルを削除するとき、その作成ステートメント内で定義された制約もまた削除されます。
      
それは、もし削除されたテーブルを再作成すると、それに参照をつける外部キー制約と同一の定義を持つはずです。それは右側のカラム名と型を持ち、先に述べたように参照キー上にインデックスを持つはずです。もしそれらが満たされなければ、MySQL はエラー番号 1005 を返し、エラーメッセージ内で エラー 150 を参照します。
        もし MySQL が
        CREATETABLE
        ステートメントからエラー番号 1005
        を報告し、そのエラーメッセージがエラー 150
        を参照していたら、外部キー制約が正しく形作られていないためにテーブル作成は失敗します。同じように、もし
        ALTERTABLE
        が失敗し、それがエラー 150
        を参照していたら、それは変更したテーブルに対して外部キー制約が間違って形作られるという意味になります。サーバー内に一番新しい
        InnoDB
        外部キーエラーの詳細説明を表示するために
        SHOW ENGINE INNODB STATUS
        を利用することができます。
      
          ANSI/ISO SQL
          標準を熟知しているユーザーであれば、参照整合性制約定義で使用されている
          MATCH
          節を認識または実行するストレージエンジンは、InnoDB
          も含めて存在しない点に注意してください。明示的な
          MATCH
          節を使用しても、規定された効果が得られないだけでなく、ON
          DELETE および ON
          UPDATE
          節が無視されてしまいます。これらの理由により、MATCH
          を指定するのは避けるべきです。
        
          SQL 標準の MATCH
          節は、複合 (複数カラム) 外部キーの
          NULL
          値が主キーとの比較時にどのように処理されるのかを制御します。InnoDB
          は基本的に MATCH
          SIMPLE
          で定義されたセマンティクスを実装していますが、このセマンティクスでは外部キーの一部または全部を
          NULL
          にすることができます。その場合、そうした外部キーを含む
          (子テーブルの)
          行は、挿入が許可されますが、参照 (親)
          テーブルのどの行ともマッチしません。トリガーを使ってほかのセマンティクスを実装することが可能です。
        
          さらに、MySQL や
          InnoDB
          では、参照カラムにインデックスを設定してパフォーマンスを向上させる必要があります。ところがシステムは、参照カラムを
          UNIQUE にしたり
          NOT NULL
          として宣言したりしなければならないという要件を強制しません。UPDATE
          や DELETE CASCADE
          などの操作では、非ユニークキーや
          NULL
          値を含むキーへの外部キー参照の処理が明確に定義されていません。UNIQUE
          かつ NOT NULL
          なキーのみを参照する外部キーを使用することをお勧めします。
        
          さらに、InnoDB
          は、(SQL 標準で定義されている)
          参照をカラム指定の一部として定義する
          「インライン
          REFERENCES 指定」
          の認識やサポートを行いません。InnoDB
          が REFERENCES
          節を受け付けるのは、独立した
          FOREIGN KEY
          指定の一部としてこの節が指定された場合だけです。MySQL
          サーバーはその他のストレージエンジンでは、外部キーの指定を解析時に無視します。
        
        SQL
        スタンダードからの逸脱:InnoDB
        は同じ参照キー値を持つ親テーブル内にいくつかの行があると、外部キーチェック内で同じキー値を持つ別の親行がまるで存在しないかのように機能します。たとえば、もし
        RESTRICT
        型制約を定義し、いくつかの親行を持つ子行があれば、InnoDB
        はそれらの親行の削除を許可しません。
      
        InnoDB
        は、外部キー制約に対応するインデックス内のレコードに基づいた、縦型アルゴリズムを通して転送操作を行います。
      
        SQL
        スタンダードからの逸脱:非
        UNIQUE キーを参照する
        FOREIGN KEY
        制約はスタンダード SQL
        ではありません。それはスタンダード SQL への
        InnoDB 拡張子です。
      
        SQL
        スタンダードからの逸脱:もし
        ON UPDATE CASCADE か
        ON UPDATE SET NULL
        が転送の最中にすでに更新された
        同じテーブル
        の更新を反復すると、それは
        RESTRICT
        のように機能します。これは、自己参照型
        ON UPDATE CASCADE か
        ON UPDATE SET NULL
        操作を利用することができないという意味です。これは転送更新の結果に起きる無限ループを防ぐためのものです。反対に、自己参照型
        ON DELETE SET NULL
        は、自己参照型 ON DELETE
        CASCADE と同様可能です。転送操作は 15
        レベルより深くネスト化されることはないでしょう。
      
        SQL
        スタンダードからの逸脱:通常の MySQL
        のように、挿入、削除、または多くの行の更新を行う
        SQL
        ステートメント内では、InnoDB
        は UNIQUE と
        FOREIGN KEY
        制約を行ごとに行います。SQL
        スタンダードによると、デフォルト動作は据え置き確認でなければいけません。それは、SQL
        ステートメント全体
        が処理されたあとに制約の確認だけが行われるいうことです。InnoDB
        が据え置き制約チェックを実装するまでは、外部キーを通してそれ自身を参照するレコードを削除するというような、いくつかの操作を行うことが不可能になります。
      

