PostgreSQLチュートリアル:ON DELETE CASCADE制約の追加と動作確認
PostgreSQLでは、「ON DELETE CASCADE」制約を使用して、親テーブルのレコードが削除された際に、関連する子テーブルのレコードを自動的に削除することができます。これは、データの整合性を保ち、意図しないデータ損失を防ぐために役立ちます。
手順
外部キー制約の追加
まず、子テーブルに親テーブルを参照する外部キー制約を作成する必要があります。
CREATE TABLE child_table (
id SERIAL PRIMARY KEY,
parent_id INTEGER REFERENCES parent_table(id)
);
ON DELETE CASCADE オプションの追加
次に、REFERENCES
句に ON DELETE CASCADE
オプションを追加します。
CREATE TABLE child_table (
id SERIAL PRIMARY KEY,
parent_id INTEGER REFERENCES parent_table(id) ON DELETE CASCADE
);
動作確認
親テーブルからレコードを削除すると、関連する子テーブルのレコードも自動的に削除されます。
-- 親テーブルのレコードを挿入
INSERT INTO parent_table (name) VALUES ('parent_1');
-- 子テーブルのレコードを挿入
INSERT INTO child_table (parent_id) VALUES (1);
-- 親テーブルのレコードを削除
DELETE FROM parent_table WHERE name = 'parent_1';
-- 子テーブルのレコードが削除されていることを確認
SELECT * FROM child_table;
補足
ON DELETE CASCADE
オプションは、親テーブルと子テーブル間に親子関係が存在する必要があることに注意してください。ON DELETE CASCADE
オプションを使用すると、意図しないデータ損失が発生する可能性があります。使用前に、アプリケーションの要件を慎重に検討する必要があります。ON DELETE CASCADE
オプションの代わりに、ON DELETE RESTRICT
オプションを使用することもできます。このオプションは、親テーブルのレコードが削除されると、関連する子テーブルのレコードの削除を阻止します。
-- テーブル作成
CREATE TABLE parent_table (
id SERIAL PRIMARY KEY,
name VARCHAR(255)
);
CREATE TABLE child_table (
id SERIAL PRIMARY KEY,
parent_id INTEGER REFERENCES parent_table(id) ON DELETE CASCADE
);
-- データ挿入
INSERT INTO parent_table (name) VALUES ('親レコード1'), ('親レコード2');
INSERT INTO child_table (parent_id) VALUES (1), (1), (2);
-- 親レコード1を削除
DELETE FROM parent_table WHERE id = 1;
-- 子レコードを確認
SELECT * FROM child_table;
-- 結果:
-- id | parent_id
-- --- | ---
-- 2 | 2
ON DELETE CASCADE
オプションにより、parent_table
から id=1
のレコードを削除すると、child_table
から parent_id=1
のレコードも自動的に削除されます。
PostgreSQLで「ON DELETE CASCADE」制約の代替方法
トリガーを使用して、親テーブルのレコードが削除された際に、関連する子テーブルのレコードを削除することができます。
利点
- より柔軟な制御が可能
- 複雑なロジックを実装できる
欠点
- 実装が複雑
- パフォーマンスの低下
例
CREATE TRIGGER delete_child_on_parent_delete
AFTER DELETE ON parent_table
FOR EACH ROW
BEGIN
DELETE FROM child_table WHERE parent_id = OLD.id;
END;
外部キー制約を無効にしてから、親テーブルと子テーブルのレコードを個別に削除することができます。
- 実装が簡単
- データの整合性が損なわれる可能性がある
ALTER TABLE child_table
DISABLE CONSTRAINT fk_child_parent;
DELETE FROM parent_table WHERE id = 1;
DELETE FROM child_table WHERE parent_id = 1;
ALTER TABLE child_table
ENABLE CONSTRAINT fk_child_parent;
アプリケーションロジックを使用して、親テーブルと子テーブルのレコードを削除することができます。
- アプリケーションロジックと統合しやすい
- コードの冗長性が増す
def delete_parent_and_child(parent_id):
# 親テーブルのレコードを削除
delete_from_parent_table(parent_id)
# 子テーブルのレコードを削除
delete_from_child_table(parent_id)
# 親レコード1を削除
delete_parent_and_child(1)
postgresql constraints cascade