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の内容。外部キー名も「'」や「"」で囲む必要なし