PostgreSQL「ON DELETE CASCADE」でデータの整合性を保ちながら関連レコードを自動削除
PostgreSQLにおける「ON DELETE CASCADE」の仕組みとプログラミング解説
この解説では、PostgreSQLにおける「ON DELETE CASCADE」機能について、その仕組みとプログラミング例を分かりやすく解説します。
「ON DELETE CASCADE」とは
「ON DELETE CASCADE」は、PostgreSQLで提供される外部キー制約の一種であり、親テーブルからレコードが削除された際に、関連する子テーブルのレコードも自動的に削除する機能です。
2 メリット
- 複雑なデータ構造への不適応:複雑な親子関係を持つデータ構造の場合、「ON DELETE CASCADE」を使用すると、予期しないレコード削除が発生する可能性があり、不都合が生じる場合があります。
1 外部キー制約の定義
「ON DELETE CASCADE」を使用するには、外部キー制約を定義する際にON DELETE CASCADEオプションを指定する必要があります。
CREATE TABLE child_table (
child_id INT PRIMARY KEY,
parent_id INT REFERENCES parent_table(parent_id) ON DELETE CASCADE
);
上記の例では、child_table
テーブルのparent_id
列がparent_table
テーブルのparent_id
列を参照する外部キー制約を定義しています。ON DELETE CASCADEオプションを指定することで、parent_table
テーブルからレコードが削除された際に、child_table
テーブルの関連するレコードも自動的に削除されるようになります。
2 制約の削除
既存の外部キー制約から「ON DELETE CASCADE」オプションを削除するには、ALTER TABLEコマンドを使用します。
ALTER TABLE child_table
MODIFY COLUMN parent_id REFERENCES parent_table(parent_id) NOT ON DELETE CASCADE;
注意事項
- 「ON DELETE CASCADE」を使用する前に、データベースの構造とデータの関係を十分に理解しておくことが重要です。
- 誤操作によるデータ損失のリスクを軽減するために、適切な権限設定やバックアップ体制を構築する必要があります。
- 複雑なデータ構造の場合は、「ON DELETE CASCADE」の代わりにON DELETE RESTRICTやON DELETE SET NULLなどのオプションを検討する必要があります。
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT REFERENCES customers(customer_id) ON DELETE CASCADE
);
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
customer_name VARCHAR(255)
);
このコードは、以下の2つのテーブルを作成します。
orders
テーブル: 注文情報を持つテーブルorder_id
: 注文ID (主キー)customer_id
: 顧客ID (外部キー)
customers
テーブル: 顧客情報を持つテーブルcustomer_name
: 顧客名
orders
テーブルのcustomer_id
列はcustomers
テーブルのcustomer_id
列を参照する外部キー制約であり、ON DELETE CASCADEオプションが指定されています。これは、customers
テーブルから顧客レコードが削除された際に、orders
テーブルの関連する注文レコードも自動的に削除されることを意味します。
データの挿入
INSERT INTO customers (customer_id, customer_name) VALUES
(1, 'Taro Yamada'),
(2, 'Hanako Sato');
INSERT INTO orders (order_id, customer_id) VALUES
(1, 1),
(2, 1),
(3, 2);
このコードは、以下のデータレコードを各テーブルに挿入します。
customers
テーブル- 顧客ID 1: 名前は「Taro Yamada」
- 顧客ID 2: 名前は「Hanako Sato」
orders
テーブル- 注文ID 1: 顧客ID 1
顧客レコードの削除
DELETE FROM customers WHERE customer_id = 1;
このコードは、顧客ID 1の顧客レコードをcustomers
テーブルから削除します。
確認
SELECT * FROM orders;
上記のコードを実行すると、以下の結果が得られます。
order_id | customer_id
---------+-------------
2 | 1
PostgreSQLにおける「ON DELETE」オプションと代替方法
PostgreSQLの「ON DELETE」オプションには、CASCADE以外にもRESTRICT、SET NULL、SET DEFAULTの3つの種類があります。それぞれのオプションは、親レコードが削除された際の関連子レコードの処理方法を異なって定義します。
オプションの詳細
- CASCADE: 既にご紹介したように、親レコードが削除されると、関連子レコードも自動的に削除されます。
- RESTRICT: 親レコードが参照されている場合、親レコードの削除を拒否します。
適切な「ON DELETE」オプションは、データベースの構造とデータの関係、およびアプリケーションの要件によって異なります。
- CASCADE: データの一貫性を維持し、関連レコードの削除を自動化したい場合に適しています。ただし、誤操作によるデータ損失のリスクが高くなります。
- RESTRICT: データの一貫性を厳密に保ちたい場合や、誤操作によるデータ損失を避けたい場合に適しています。ただし、関連レコードの削除操作が煩雑になる可能性があります。
- SET NULL: 関連レコードを完全に削除したくないが、親レコードとの参照関係を解除したい場合に適しています。ただし、NULL値の処理方法をアプリケーション側で考慮する必要があります。
- SET DEFAULT: 関連レコードを完全に削除したくないが、親レコードとの参照関係を明確に定義したい場合に適しています。ただし、デフォルト値の適切な設定が必要となります。
代替方法
「ON DELETE」オプション以外にも、関連レコードの削除を処理する方法があります。
- トリガー: 親レコードの削除時に実行されるトリガーを作成することで、関連レコードの削除処理を独自に定義することができます。柔軟性の高い処理が可能ですが、複雑なロジックを記述する必要があり、メンテナンスが大変になる可能性があります。
- アプリケーションロジック: アプリケーション側でロジックを記述することで、関連レコードの削除処理を制御することができます。データベースへの負荷を軽減できますが、アプリケーションロジックが複雑になり、保守性が低下する可能性があります。
sql postgresql cascade