fuelphp / mysql 外部キーの制約
複雑なテーブル構成になってくると誤ってマスターを削除する可能性が高くなる…防ぐには外部キーの制約を設定しておくのが無難
作成日:2024-10-29, 更新日:2024-10-30
対象のキー
参照元と参照先で型などをきっちりと合わせておく必要がある
fuelPHP: マイグレーションファイル
<?php namespace Fuel\Migrations; class 〇〇〇 { const TABLE_NAME = '対象テーブル'; const SEED = array( array( 'key' => '〇〇〇', // 対象カラム 'master_table' => '〇〇〇', // 参照元テーブル 'master_colm' => '〇〇〇', // 参照元カラム ), // array( // 'key' => '〇〇〇', // 対象カラム // 'master_table' => '〇〇〇', // 参照元テーブル // 'master_colm' => '〇〇〇', // 参照元カラム // ), ); public function make_constraint($key) { return 'foreignkey_' . self::TABLE_NAME . '_' . $key; } public function up() { foreach (self::SEED as $row_seed) { $constraint = self::make_constraint($row_seed['key']); \DBUtil::add_foreign_key(self::TABLE_NAME, [ 'constraint' => $constraint, 'key' => $row_seed['key'], 'reference' => [ 'table' => $row_seed['master_table'], 'column' => $row_seed['master_colm'], ], 'on_delete' => 'RESTRICT', // 紐づくレコードがある限り、参照元の削除はNG 'on_update' => 'RESTRICT', // 紐づくレコードがある限り、参照元の更新はNG // 'on_update' => 'CASCADE', // 紐づくレコードがあり、参照元が更新された場合、紐づくカラムも更新 ]); } } public function down() { foreach (self::SEED as $row_seed) { $constraint = self::make_constraint($row_seed['key']); \DBUtil::drop_foreign_key(self::TABLE_NAME, $constraint); } } }
クエリ
外部キーの制約の設定
ALTER TABLE `〇〇〇` -- 対象テーブル ADD CONSTRAINT `〇〇〇` -- 外部キー名 FOREIGN KEY (`〇〇〇`) -- 対象カラム名 REFERENCES `〇〇〇` -- 参照元になるマスターテーブル名 (`〇〇〇`) -- 参照元になるカラム名 ON DELETE RESTRICT -- 参照元を削除したときの挙動。RESTRICTは参照元の削除はNG ON UPDATE RESTRICT -- 参照元を修正したときの挙動。RESTRICTは参照元の削除はNG ;
外部キーの制約の確認
SELECT TABLE_NAME, -- 対象テーブル COLUMN_NAME, -- 対象カラム CONSTRAINT_NAME, -- 外部キー名 REFERENCED_TABLE_NAME, -- 参照元のテーブル REFERENCED_COLUMN_NAME -- 参照元のカラム FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '〇〇〇' -- データベース名を指定 # AND TABLE_NAME = '〇〇〇' -- 対象のテーブル名を指定 AND REFERENCED_TABLE_NAME IS NOT NULL;
対象テーブルで絞り込みたいとき
SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '〇〇〇' -- データベース名を指定 AND TABLE_NAME = '〇〇〇' -- 対象のテーブル名を指定 AND REFERENCED_TABLE_NAME IS NOT NULL;
外部キーの制約の削除
ALTER TABLE テーブル名 DROP FOREIGN KEY 外部キー名; -- CONSTRAINT_NAMEの内容。外部キー名も「'」や「"」で囲む必要なし