質問: "CREATE TABLE IF NOT EXISTS wp_seconds ( -- カラムを設定 ID BIGINT(20) UNSIGNED NOT NULL, first_ID BIGINT(20) UNSIGNED NOT NULL , sentence VARCHAR(100) NOT NULL, -- 主キーを設定 PRIMARY KEY (ID), -- インデックスを設定 INDEX idx_wp_seconds_01(sentence), -- 外部キーを設定 FOREIGN KEY (first_ID) REFERENCES wp_firsts(ID), CONSTRAINT fk_wp_seconds_01 FOREIGN KEY (first_ID) REFERENCES wp_firsts(ID) );"; add_option($table."_version", '1.0'); $wpdb->query($sql); } ``` ### 試したこと `wp_seconds`テーブルに対し`SHOW CREATE TABLE`を実行すると以下の出力を得ましたが、さらに訳の分からないことになりました。 ``` CREATE TABLE `wp_seconds` ( `ID` bigint(20) unsigned NOT NULL, `first_ID` bigint(20) unsigned NOT NULL, `sentence` varchar(100) NOT NULL, PRIMARY KEY (`ID`), KEY `idx_wp_seconds_01` (`sentence`), KEY `fk_wp_seconds_01` (`first_ID`), CONSTRAINT `fk_wp_seconds_01` FOREIGN KEY (`first_ID`) REFERENCES `wp_firsts` (`ID`), CONSTRAINT `wp_seconds_ibfk_1` FOREIGN KEY (`first_ID`) REFERENCES `wp_firsts` (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ``` この結果によれば、外部キーの設定はいずれも`CONSTRAINT`を介してされているのです。 ならばなぜ、`fk_wp_seconds_01`だけインデックスが貼られ、`wp_seconds_ibfk_1`は貼られないのか...訳がわからなくなてきました。 ### 補足情報(FW/ツールのバージョンなど) サーバーはGMOサーバーです。 データベースはMariaDBの10.1.11です。 PHPは7.2です。
回答: ### 【1】について 「> `CONSTRAINT`を介さないと、インデックスが貼られない」 ではなく、 「`CONSTRAINT`を介さなくてもインデックスは貼られるが、しかし同じインデックスは上書きされるために貼られないのだと誤解されてしまった」 です。 改めて`create_wp_seconds`の下記コードを見てみましょう。 ``` -- 外部キーを設定 FOREIGN KEY (first_ID) REFERENCES wp_firsts(ID), CONSTRAINT fk_wp_seconds_01 FOREIGN KEY (first_ID) REFERENCES wp_firsts(ID) ``` このコードによって後者の`CONSTRAINT`を介した方のインデックスで上書きされ、だから図のように`fk_wp_seconds_01`というインデックスだけが残っているのです。 前者の`CONSTRAINT`を介さない方は「> インデックスが貼られずに済んでいる」というわけではなく、後者で上書きされただけということですね。 ### 【2】について できません。 仮に外部キーを登録したのちに`DROP INDEX`を試みてもエラーになるでしょう。 MySQLもMariaDBも、外部キーは常にインデックスとセットです。 ### 【3】について 個人的には名前をつけられる点に鑑みて`CONSTRAINT`の方法を採用しています。