【SQL】DROP TABLEでテーブルを削除する方法|IF EXISTS・CASCADE・TRUNCATE違い・RDBMS別構文

データベースのテーブル削除は、開発・運用で頻繁に行う操作です。SQLのDROP TABLE文を使えば、不要になったテーブルを完全に削除できます。

しかし、DROP TABLEは取り消し不可能な操作のため、正しい知識がないと本番環境で重大な事故を起こしかねません。この記事では、基本構文からIF EXISTSによる安全な削除外部キー制約の対処法DROP TABLE・TRUNCATE TABLE・DELETEの違いRDBMS別の構文比較まで、実務で必要な知識を網羅的に解説します。

この記事で学べること

  • DROP TABLEの基本構文と実行例
  • IF EXISTSでエラーを防ぐ安全な削除方法
  • 複数テーブルの一括削除
  • CASCADE CONSTRAINTSで外部キー制約ごと削除
  • DROP TABLE・TRUNCATE TABLE・DELETEの使い分け
  • INFORMATION_SCHEMAでテーブル存在を確認する方法
  • MySQL・PostgreSQL・SQL Server・Oracle・SQLite別の構文比較
  • 一時テーブルの削除方法
  • よくあるエラーと対処法
  • 実務での安全なテーブル削除パターン
スポンサーリンク

DROP TABLEの基本構文

DROP TABLE文は、データベースからテーブルを完全に削除するSQL文です。テーブル定義(構造)とデータの両方が削除されます。

基本構文
DROP TABLE テーブル名;
実行例
-- employeesテーブルを削除
DROP TABLE employees;

実行結果

Query OK, 0 rows affected (0.05 sec)

注意:DROP TABLEはDDL(Data Definition Language)に分類されます。実行すると自動的にCOMMITされるため、ROLLBACKで元に戻すことはできません。

DROP TABLEで削除されるもの

DROP TABLEを実行すると、以下のすべてが削除されます。

削除対象 説明
テーブル定義 列名・データ型・制約などの構造情報
全データ テーブル内の全行
インデックス テーブルに紐づくすべてのインデックス
トリガー テーブルに定義されたトリガー
制約 PRIMARY KEY、UNIQUE、CHECK、DEFAULT等
権限 テーブルに付与されたGRANT(一部RDBMS)

IF EXISTSでエラーを防ぐ

存在しないテーブルにDROP TABLEを実行するとエラーになります。IF EXISTSを付けると、テーブルが存在する場合のみ削除し、存在しない場合はエラーを出さずスキップします。

IF EXISTS 構文
-- テーブルが存在する場合のみ削除
DROP TABLE IF EXISTS employees;

IF EXISTSなしの場合(エラー発生)

存在しないテーブルを削除
-- employeesテーブルが存在しない場合
DROP TABLE employees;

エラー出力

ERROR 1051 (42S02): Unknown table 'database_name.employees'

IF EXISTSありの場合(エラーなし)

IF EXISTS で安全に削除
DROP TABLE IF EXISTS employees;

実行結果

Query OK, 0 rows affected, 1 warning (0.00 sec)

ポイント:マイグレーションスクリプトやバッチ処理では、IF EXISTSを付けるのが鉄則です。テーブルの有無に関わらずスクリプトが正常に実行されるため、環境差異による失敗を防げます。

複数テーブルの一括削除

DROP TABLE文では、カンマ区切りで複数のテーブルを同時に削除できます。

複数テーブルの一括削除
-- 3つのテーブルを同時に削除
DROP TABLE employees, departments, salaries;
IF EXISTS と組み合わせ
-- 存在するテーブルだけ削除
DROP TABLE IF EXISTS employees, departments, salaries;

注意:複数テーブルの一括削除はMySQL・PostgreSQL・SQLiteで対応しています。Oracle・SQL Serverでは1テーブルずつDROP TABLE文を実行する必要があります。

外部キーの依存関係を考慮した削除順序

外部キー制約がある場合、子テーブル → 親テーブルの順序で削除する必要があります。

正しい削除順序
-- orders → customers の外部キー関係がある場合
-- 子テーブル(参照する側)を先に削除
DROP TABLE IF EXISTS orders;
-- 親テーブル(参照される側)を後に削除
DROP TABLE IF EXISTS customers;

CASCADE CONSTRAINTS で外部キー制約ごと削除

外部キー制約がある親テーブルを削除しようとすると、通常はエラーになります。CASCADEオプションを使うと、関連する外部キー制約も一緒に削除できます。

外部キーが原因のエラー例

エラーが発生するケース
-- ordersテーブルがcustomersを外部キー参照している場合
DROP TABLE customers;

エラー出力(MySQL)

ERROR 3730 (HY000): Cannot drop table 'customers' referenced by a foreign key constraint 'orders_ibfk_1' on table 'orders'.

RDBMS別のCASCADE対処法

RDBMS 対処法
PostgreSQL DROP TABLE テーブル名 CASCADE
Oracle DROP TABLE テーブル名 CASCADE CONSTRAINTS
MySQL SET FOREIGN_KEY_CHECKS = 0 で一時無効化
SQL Server 先に外部キー制約を個別に削除
SQLite 外部キーはデフォルト無効(PRAGMA foreign_keys)

PostgreSQL: CASCADE

PostgreSQL – CASCADE
-- 外部キー制約も一緒に削除(子テーブルのデータは残る)
DROP TABLE customers CASCADE;

注意:PostgreSQLのCASCADEは外部キー制約を削除するだけで、子テーブル自体やそのデータは削除しません。あくまで「制約の連鎖削除」です。

Oracle: CASCADE CONSTRAINTS

Oracle – CASCADE CONSTRAINTS
-- 外部キー制約ごとテーブルを削除
DROP TABLE customers CASCADE CONSTRAINTS;

-- PURGE を付けるとごみ箱にも残さない
DROP TABLE customers CASCADE CONSTRAINTS PURGE;

MySQL: FOREIGN_KEY_CHECKS を無効化

MySQL – 外部キーチェック無効化
-- 外部キーチェックを一時的に無効化
SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS customers;

-- 外部キーチェックを再度有効化
SET FOREIGN_KEY_CHECKS = 1;

注意:FOREIGN_KEY_CHECKSを無効化した状態で親テーブルを削除すると、子テーブルの外部キー制約は宙ぶらりんになります。子テーブルの制約も手動で削除するか、子テーブルごと削除してください。

SQL Server: 外部キー制約を個別に削除

SQL Server – 制約を先に削除
-- 1. 外部キー制約を先に削除
ALTER TABLE orders
DROP CONSTRAINT FK_orders_customers;

-- 2. テーブルを削除
DROP TABLE customers;

DROP TABLE・TRUNCATE TABLE・DELETEの違い

テーブルのデータを消す方法は3つあります。それぞれの特徴と使い分けを理解しておきましょう。

比較項目 DROP TABLE TRUNCATE TABLE DELETE
テーブル定義 削除される 残る 残る
データ 全削除 全削除 条件指定可
WHERE句 不可 不可 可能
ROLLBACK 不可(DDL) 不可(DDL) 可能(DML)
AUTO_INCREMENT 消える リセット 継続
トリガー発火 しない しない する
速度 高速 高速 低速(大量データ時)
SQL分類 DDL DDL DML

使い分けの目安

使い分けの例
-- テーブル自体が不要 → DROP TABLE
DROP TABLE IF EXISTS tmp_work_data;

-- テーブル構造は残して全データを削除 → TRUNCATE TABLE
TRUNCATE TABLE access_logs;

-- 特定の条件に合うデータだけ削除 → DELETE
DELETE FROM access_logs
WHERE created_at < '2024-01-01';

ポイント:開発環境でテーブルを作り直す場合はDROP TABLE → CREATE TABLEのセットが定番です。本番環境で全データを消すだけならTRUNCATE TABLEを使います。

テーブルの存在確認方法

DROP TABLEの前にテーブルの存在を確認したい場合、INFORMATION_SCHEMAやRDBMS固有のコマンドが使えます。

INFORMATION_SCHEMA(標準SQL)

MySQL / SQL Server / PostgreSQL
-- テーブルが存在するか確認
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_database'
  AND TABLE_NAME = 'employees';

実行結果(テーブルが存在する場合)

+------------+
| TABLE_NAME |
+------------+
| employees  |
+------------+
1 row in set (0.00 sec)

RDBMS別のテーブル一覧確認コマンド

RDBMS テーブル一覧コマンド
MySQL SHOW TABLES;
PostgreSQL \dt または SELECT * FROM pg_tables;
SQL Server SELECT * FROM sys.tables;
Oracle SELECT * FROM user_tables;
SQLite .tables または SELECT * FROM sqlite_master;

SQL Server: IF EXISTSの代替(OBJECT_ID)

SQL Server 2016より前のバージョンではIF EXISTS構文が使えないため、OBJECT_ID関数で存在確認します。

SQL Server – OBJECT_IDで存在確認
-- SQL Server 2016以降
DROP TABLE IF EXISTS employees;

-- SQL Server 2014以前
IF OBJECT_ID('dbo.employees', 'U') IS NOT NULL
  DROP TABLE dbo.employees;

RDBMS別のDROP TABLE構文比較

DROP TABLEの構文はRDBMSによって微妙に異なります。ここでは主要5つのRDBMSの構文を比較します。

MySQL

MySQL
-- 基本
DROP TABLE employees;

-- IF EXISTS付き
DROP TABLE IF EXISTS employees;

-- 複数テーブル一括削除
DROP TABLE IF EXISTS employees, departments;

-- 一時テーブル削除
DROP TEMPORARY TABLE IF EXISTS tmp_work;

PostgreSQL

PostgreSQL
-- 基本
DROP TABLE employees;

-- IF EXISTS付き
DROP TABLE IF EXISTS employees;

-- CASCADE(外部キー制約も削除)
DROP TABLE IF EXISTS employees CASCADE;

-- RESTRICT(参照されていればエラー ※デフォルト)
DROP TABLE employees RESTRICT;

SQL Server

SQL Server
-- 基本
DROP TABLE employees;

-- IF EXISTS付き(SQL Server 2016以降)
DROP TABLE IF EXISTS employees;

-- スキーマ指定
DROP TABLE dbo.employees;

-- 旧バージョン対応
IF OBJECT_ID('dbo.employees', 'U') IS NOT NULL
  DROP TABLE dbo.employees;

Oracle

Oracle
-- 基本(ごみ箱に入る)
DROP TABLE employees;

-- 完全削除(ごみ箱に入れない)
DROP TABLE employees PURGE;

-- 外部キー制約ごと削除
DROP TABLE employees CASCADE CONSTRAINTS;

-- 完全削除 + 外部キー制約ごと
DROP TABLE employees CASCADE CONSTRAINTS PURGE;

ポイント:OracleのDROP TABLEはIF EXISTS構文がありません(23c以降で対応予定)。存在確認が必要な場合はPL/SQLで対処します。

SQLite

SQLite
-- 基本
DROP TABLE employees;

-- IF EXISTS付き
DROP TABLE IF EXISTS employees;

RDBMS別対応状況まとめ

機能 MySQL PostgreSQL SQL Server Oracle SQLite
IF EXISTS ○(2016〜) ✕(23c〜)
複数テーブル一括
CASCADE
PURGE
TEMPORARY指定

一時テーブルの削除

一時テーブル(TEMPORARY TABLE)はセッション終了時に自動削除されますが、明示的に削除することもできます。

MySQL: DROP TEMPORARY TABLE

MySQL – 一時テーブルの作成と削除
-- 一時テーブルを作成
CREATE TEMPORARY TABLE tmp_results (
  id INT,
  name VARCHAR(100)
);

-- 一時テーブルのみを削除(通常テーブルは影響なし)
DROP TEMPORARY TABLE IF EXISTS tmp_results;

ポイント:DROP TEMPORARY TABLEは一時テーブルだけを対象にするため、同名の通常テーブルを誤って削除する心配がありません。MySQLでは一時テーブルと通常テーブルが同名でも共存できます。

PostgreSQL・SQL Server

PostgreSQL / SQL Server – 一時テーブルの削除
-- PostgreSQL: 通常のDROP TABLEで削除
DROP TABLE IF EXISTS tmp_results;

-- SQL Server: #付きの一時テーブル
DROP TABLE IF EXISTS #tmp_results;

-- SQL Server: ##付きのグローバル一時テーブル
DROP TABLE IF EXISTS ##tmp_results;
RDBMS 一時テーブルの削除方法 自動削除タイミング
MySQL DROP TEMPORARY TABLE セッション終了時
PostgreSQL DROP TABLE(通常と同じ) セッション終了時(ON COMMIT DROPも可)
SQL Server DROP TABLE #テーブル名 セッション終了時 / バッチ終了時
Oracle DROP TABLE(通常と同じ) トランザクション/セッション終了時
SQLite DROP TABLE(通常と同じ) 接続終了時

DROP TABLE後のデータ復旧について

DROP TABLEで削除したテーブルとデータを元に戻せるかは、RDBMSと事前の対策によって異なります。

RDBMS 復旧方法 条件
Oracle FLASHBACK TABLE(ごみ箱復元) PURGEしていない場合のみ
SQL Server トランザクションログからの復旧 完全復旧モデルの場合のみ
MySQL バックアップからの復元 事前にバックアップが必要
PostgreSQL バックアップからの復元 事前にバックアップが必要
SQLite ファイルバックアップからの復元 事前にファイルコピーが必要

Oracle: FLASHBACK TABLEで復旧

Oracle – ごみ箱から復元
-- ごみ箱の中身を確認
SELECT object_name, original_name, type
FROM user_recyclebin;

-- テーブルを復元
FLASHBACK TABLE employees TO BEFORE DROP;

-- 別名で復元
FLASHBACK TABLE employees TO BEFORE DROP RENAME TO employees_restored;

注意:DROP TABLE ... PURGEで削除した場合、ごみ箱に入らないためFLASHBACK TABLEでの復旧は不可能です。復旧の可能性を残すなら、PURGEは付けないようにしましょう。

MySQL: バックアップからの復旧

MySQL – mysqldumpからの復元
-- 事前にバックアップを取得しておく
mysqldump -u root -p my_database employees > employees_backup.sql

-- 復元する場合
mysql -u root -p my_database < employees_backup.sql

よくあるエラーと対処法

エラー 原因 対処法
Unknown table テーブルが存在しない IF EXISTSを使う
foreign key constraint fails 他のテーブルから参照されている CASCADE / FOREIGN_KEY_CHECKS=0
Access denied DROP権限がない GRANTで権限を付与
table is locked テーブルがロックされている UNLOCK TABLESまたはセッション終了を待つ
syntax error 予約語をテーブル名に使用 バッククォートで囲む
table doesn't exist in engine メタデータと実体の不整合 .frmファイルを手動削除後に再作成

エラー1: テーブルが存在しない

エラーと対処法
-- エラーが出る
DROP TABLE non_existent_table;
-- ERROR 1051 (42S02): Unknown table 'db.non_existent_table'

-- 対処: IF EXISTSを付ける
DROP TABLE IF EXISTS non_existent_table;

エラー2: 外部キー制約によるエラー

MySQL - 外部キーエラーの対処
-- エラーが出る場合
DROP TABLE customers;
-- ERROR 3730: Cannot drop table referenced by foreign key

-- 対処1: 外部キーチェックを無効化
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE customers;
SET FOREIGN_KEY_CHECKS = 1;

-- 対処2: 子テーブルを先に削除
DROP TABLE orders;   -- 子テーブルを先に
DROP TABLE customers; -- 親テーブルを後に

エラー3: 権限不足

MySQL - DROP権限の付与
-- 現在の権限を確認
SHOW GRANTS FOR 'username'@'localhost';

-- DROP権限を付与(管理者が実行)
GRANT DROP ON my_database.* TO 'username'@'localhost';
FLUSH PRIVILEGES;

エラー4: 予約語がテーブル名に使われている

予約語テーブルの削除
-- "order"は予約語なのでエラーになる
DROP TABLE order;
-- ERROR 1064: Syntax error

-- 対処: バッククォート(MySQL)やダブルクォート(標準SQL)で囲む
DROP TABLE `order`;        -- MySQL
DROP TABLE "order";        -- PostgreSQL / Oracle
DROP TABLE [order];        -- SQL Server

実務での安全なテーブル削除パターン

本番環境でテーブルを削除する際は、以下の手順に沿って安全に作業を進めましょう。

ステップ1: 事前確認

事前確認 - テーブル構造とデータ件数
-- 1. テーブルの存在とデータ件数を確認
SELECT COUNT(*) AS row_count
FROM employees;

-- 2. 外部キー制約を確認(MySQL)
SELECT
  TABLE_NAME,
  CONSTRAINT_NAME,
  REFERENCED_TABLE_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_NAME = 'employees';

-- 3. テーブル構造を確認
DESCRIBE employees;

ステップ2: バックアップ取得

バックアップ取得
-- MySQLの場合: mysqldumpでバックアップ
mysqldump -u root -p my_database employees > backup_employees_$(date +%Y%m%d).sql

-- SQL内でバックアップテーブルを作成する方法もある
CREATE TABLE employees_backup_20240301 AS
SELECT * FROM employees;

ステップ3: リネーム → 確認 → 削除

いきなりDROP TABLEするのではなく、リネームして問題がないか確認してから削除する方法が最も安全です。

安全な削除パターン(リネーム方式)
-- ステップ1: テーブルをリネーム(_dropme接尾辞を付ける)
ALTER TABLE employees
RENAME TO _employees_dropme_20240301;

-- ステップ2: アプリケーションに影響がないか1〜2週間確認
-- (エラーが出たらリネームを戻せばOK)

-- ステップ3: 問題なければ削除
DROP TABLE _employees_dropme_20240301;

実務での安全な削除チェックリスト

  • 対象テーブルのデータ件数を確認した
  • テーブルを参照している外部キー制約を確認した
  • テーブルを使っているビュー・ストアドプロシージャがないか確認した
  • アプリケーションコードで当該テーブルを参照している箇所がないか確認した
  • バックアップを取得した
  • 可能であればリネーム方式で一定期間運用確認した
  • 作業はメンテナンス時間帯に実施する

マイグレーションスクリプトでのパターン

フレームワークのマイグレーション機能を使わず、手動でSQLスクリプトを実行する場合の安全なパターンです。

安全なマイグレーションスクリプト(MySQL)
-- ============================================
-- マイグレーション: 不要テーブルの削除
-- 実行日: 2024-03-01
-- 対象: old_logs, temp_data, deprecated_config
-- ============================================

-- バックアップテーブル作成
CREATE TABLE IF NOT EXISTS _bak_old_logs AS
  SELECT * FROM old_logs;

-- 外部キーチェックを一時停止
SET FOREIGN_KEY_CHECKS = 0;

-- テーブル削除
DROP TABLE IF EXISTS old_logs;
DROP TABLE IF EXISTS temp_data;
DROP TABLE IF EXISTS deprecated_config;

-- 外部キーチェックを復元
SET FOREIGN_KEY_CHECKS = 1;

まとめ

DROP TABLEは、テーブルの定義・データ・インデックスをすべて削除するSQL文です。最後に要点を整理しておきましょう。

ポイント 内容
基本構文 DROP TABLE テーブル名;
安全な削除 IF EXISTSを付けてエラーを防ぐ
外部キー対処 CASCADE(PostgreSQL/Oracle)またはFOREIGN_KEY_CHECKS=0(MySQL)
TRUNCATE TABLE との違い DROP=テーブル自体を削除、TRUNCATE=データだけ削除
データ復旧 Oracle以外は基本的にバックアップからのみ復旧可能
実務のコツ バックアップ取得 → リネーム → 確認 → 削除の手順

ポイント:DROP TABLEは取り消しができない強力なコマンドです。特に本番環境では、バックアップ取得 → リネーム → 動作確認 → 削除の手順を徹底し、事故を未然に防ぎましょう。