テーブルを削除 - DROP TABLE
テーブル削除の DDL。CASCADE / RESTRICT、IF EXISTS の使い分けと事故防止のポイント
概念図
構文
sql
DROP TABLE [IF EXISTS] table_name [CASCADE | RESTRICT];サンプル
安全に削除するための IF EXISTS と、依存関係ごと削除する CASCADE の例
sql
-- 存在するときだけ削除
DROP TABLE IF EXISTS staging_import;
-- 外部キーで参照されている場合は CASCADE が必要(PostgreSQL)
DROP TABLE orders CASCADE;DROP TABLE の基本
DROP TABLE はテーブル自体と、そのテーブル上のインデックス・制約・トリガーを削除します。データは元に戻せません(バックアップからの復元が必要)。
削除対象のテーブルに対して他のオブジェクトが依存している場合、標準では削除が失敗します。
CASCADE と RESTRICT
RESTRICT(多くの RDBMS で既定)は、他のオブジェクトから参照されている場合に削除を拒否します。CASCADE は依存オブジェクト(ビュー、外部キー制約、場合によっては依存する他のテーブル行など)もまとめて削除します。
CASCADE は便利ですが、想定外のビューや制約まで消えて本番事故になりがちなので、本番実行前に必ず依存関係を確認してください。
sql
-- PostgreSQL: 依存関係の事前確認
SELECT dependent_ns.nspname AS schema, dependent_view.relname AS view
FROM pg_depend
JOIN pg_rewrite ON pg_depend.objid = pg_rewrite.oid
JOIN pg_class dependent_view ON pg_rewrite.ev_class = dependent_view.oid
JOIN pg_namespace dependent_ns ON dependent_ns.oid = dependent_view.relnamespace
JOIN pg_class source_table ON pg_depend.refobjid = source_table.oid
WHERE source_table.relname = 'orders';IF EXISTS と冪等性
マイグレーションや CI で同じスクリプトが再実行される可能性があるなら DROP TABLE IF EXISTS を使い、存在しないときにエラーで落ちないようにします。
ただし、IF EXISTS はタイプミスしたテーブル名を黙って無視するので、手動運用では逆に危険です。状況に応じて使い分けましょう。
事故防止のチェックリスト
- 接続先を再確認: 本番 DB に接続していないか、プロンプト色分けや
\conninfoで確認 - トランザクションで包む: PostgreSQL は DDL もトランザクショナルなので
BEGIN; DROP TABLE ...; -- 確認してから COMMIT;が可能 - 論理削除(リネーム)で保険: いきなり DROP せず、まず
ALTER TABLE foo RENAME TO foo_to_drop_20260414;で数日寝かせる運用も有効 - CASCADE は最後の手段: 依存ビュー・外部キー・アプリコードを先に洗い出してから実行
