ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
外部キーの追加
-- 基本構文
ALTER TABLE orders
ADD FOREIGN KEY (user_id) REFERENCES users(id);
-- 制約名を明示(推奨:あとで削除が楽)
ALTER TABLE orders
ADD CONSTRAINT fk_orders_user_id
FOREIGN KEY (user_id) REFERENCES users(id);
-- カスケード動作付き
ALTER TABLE orders
ADD CONSTRAINT fk_orders_user_id
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE
ON UPDATE CASCADE;
-- 削除時は NULL に
ALTER TABLE orders
ADD CONSTRAINT fk_orders_user_id
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE SET NULL;
-- テーブル作成時に同時定義
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT,
amount DECIMAL(10, 2),
CONSTRAINT fk_orders_user_id
FOREIGN KEY (user_id) REFERENCES users(id)
);
外部キー制約名の確認
MySQL
-- SHOW CREATE TABLE
SHOW CREATE TABLE orders;
-- → 出力中の CONSTRAINT `fk_xxx` FOREIGN KEY ... を確認
-- information_schema 経由
SELECT
CONSTRAINT_NAME,
TABLE_NAME,
COLUMN_NAME,
REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM information_schema.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA = 'mydb'
AND TABLE_NAME = 'orders'
AND REFERENCED_TABLE_NAME IS NOT NULL;
-- カスケード設定込みで確認
SELECT
CONSTRAINT_NAME,
UPDATE_RULE,
DELETE_RULE
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = 'mydb'
AND TABLE_NAME = 'orders';
PostgreSQL
-- psql の \d
\d orders
-- system catalog
SELECT
conname,
pg_get_constraintdef(c.oid)
FROM pg_constraint c
JOIN pg_class t ON c.conrelid = t.oid
WHERE t.relname = 'orders'
AND c.contype = 'f';
-- information_schema
SELECT
tc.constraint_name,
kcu.column_name,
ccu.table_name AS foreign_table,
ccu.column_name AS foreign_column
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu
ON ccu.constraint_name = tc.constraint_name
WHERE tc.table_name = 'orders'
AND tc.constraint_type = 'FOREIGN KEY';
外部キーの削除
MySQL
-- 制約名を指定して削除
ALTER TABLE orders DROP FOREIGN KEY fk_orders_user_id;
-- 暗黙的に作られたインデックスは別途削除(必要に応じて)
ALTER TABLE orders DROP INDEX fk_orders_user_id;
PostgreSQL / 標準 SQL
ALTER TABLE orders DROP CONSTRAINT fk_orders_user_id;
ON DELETE / ON UPDATE のオプション
| オプション | 動作 |
|---|---|
| NO ACTION (デフォルト) | 参照先が変わったらエラーになる(安全) |
| RESTRICT | NO ACTION とほぼ同じ。即時チェック |
| CASCADE | 参照先と同じ動作を伝播(親削除なら子も削除) |
| SET NULL | 参照元を NULL に書き換える(NULL 許可カラムのみ) |
| SET DEFAULT | 参照元をデフォルト値に(PG のみ) |
外部キー一時無効化(インポート時等)
-- MySQL: セッション単位
SET FOREIGN_KEY_CHECKS = 0;
-- 大量 INSERT / TRUNCATE 等
SET FOREIGN_KEY_CHECKS = 1; -- 戻す
-- PostgreSQL: トランザクション内で
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
-- ... 処理
COMMIT;
-- ★ 注意: 制約を切ると整合性が失われる。データ整合確認後に有効化
Laravel マイグレーションでの書き方
// マイグレーション: 外部キー追加
public function up() {
Schema::table('orders', function (Blueprint $table) {
// 短縮形(Laravel 7+)
$table->foreignId('user_id')->constrained()->onDelete('cascade');
// 明示的に書く場合
$table->unsignedBigInteger('product_id');
$table->foreign('product_id')
->references('id')->on('products')
->onDelete('restrict')
->onUpdate('cascade');
});
}
// マイグレーション: 外部キー削除
public function down() {
Schema::table('orders', function (Blueprint $table) {
// 命名規則: テーブル名_カラム名_foreign
$table->dropForeign(['user_id']);
// または制約名指定
$table->dropForeign('orders_user_id_foreign');
});
}
外部キー追加でエラーになる典型例
| エラー | 原因 |
|---|---|
| Cannot add foreign key constraint | 参照先テーブル / カラムの不一致(型・charset・collation) |
| Foreign key constraint fails | 既存データに参照先に存在しない値がある → 先に整合性確保 |
| Duplicate foreign key constraint name | 制約名が重複 → 名前を変える |
| Cannot delete or update a parent row | 参照されている行を削除しようとしている → CASCADE か事前に子行削除 |
パフォーマンスへの影響
- 暗黙的にインデックスが作られる(MySQL): 外部キーカラムには自動で BTREE INDEX
- INSERT / UPDATE 時に参照チェック: 親テーブルの存在確認で若干のオーバーヘッド
- 大量 INSERT は遅くなる: バッチインポート時は一時的に無効化
- カスケード削除は重い: 数十万行の連鎖削除は時間がかかる
- 本番運用は注意深く: アプリ側ロジックで整合性を保つ方が柔軟な場合も
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
同階層のページ
- テーブル作成
- カラムの定義変更
- カラム名の変更
- カラム追加 / 削除
- インデックスの作成
- インデックスの削除
- AUTO_INCREMENTの仕様について
- AUTO_INCREMENTの追加と確認方法
- 外部キーの追加/削除と制約名の確認方法
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Laravel キャッシュクリア完全ガイド(cache:clear / config:clear / 2026-05-18 07:42:07
- プロジェクトの作成と削除 2026-05-18 07:42:07
- インストール直後にNetbeansが反応しない 2026-05-18 07:42:07
- 動画やチャンネルの検索 2026-05-18 07:42:07
- APIキー取得方法 2026-05-18 07:42:07
- チャンネル情報の取得 2026-05-18 07:42:07
- API 入門 — Web API(REST / GraphQL / gRPC / 2026-05-18 07:42:07
- インストール(eclipseプラグイン) 2026-05-18 07:42:07
- Laravel「Dotenv values containing spaces must be surrounded 2026-05-18 07:42:07
- エラー一覧 2026-05-18 07:42:07
- curl: (51) SSL: certificate subject name '~' does not match 2026-05-18 07:42:07
- インストール方法(Windows版) 2026-05-18 07:42:07
- JSONから配列に変換 2026-05-18 07:42:07
- 処理を一定時間待つ 2026-05-18 07:42:07
- A non well formed numeric value encountered 2026-05-18 07:42:07
コメントを削除してもよろしいでしょうか?