概要
DROP文は、MySQLのデータベースオブジェクトを完全に削除するためのDDL (Data Definition Language) 文である。
DROP文は、テーブル、データベース、インデックス、ビュー、ストアドプロシージャ、ファンクション、トリガー、イベント、ユーザ等、多様なデータベースオブジェクトの削除に対応している。
削除されたオブジェクトは完全に消去され、テーブルの場合はテーブル定義と全てのデータが削除される。
DROP文の実行には十分な注意が必要である。
削除されたデータの復元は、事前に取得したバックアップからのみ可能であるため、本番環境での実行前には必ずバックアップを取得することが推奨される。
IF EXISTS オプションを使用することにより、オブジェクトが存在しない場合でもエラーを発生させずに警告のみを出力できる。
これは、スクリプトやマイグレーション処理において安全性を向上させる重要な機能である。
外部キー制約が設定されている場合、親テーブルを削除しようとするとエラーが発生する。
この場合は、子テーブルを先に削除するか、FOREIGN_KEY_CHECKS を一時的に無効化する必要がある。
DROP文は、DELETE 文 や TRUNCATE 文とは異なり、テーブル構造自体を削除するため、実行後にはテーブルが存在しなくなる。
データの削除のみが目的である場合は、DELETE文やTRUNCATE文の使用を検討する必要がある。
DROP TABLE
DROP TABLE 文は、1つまたは複数のテーブルを完全に削除する。
テーブル定義と全てのデータ、トリガーが削除される。
基本構文
DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CASCADE]
| オプション | 説明 |
|---|---|
| TEMPORARY | TEMPORARYテーブルのみを削除対象とする。 永続テーブルと同名のTEMPORARYテーブルが存在する場合、永続テーブルを保護できる。 |
| IF EXISTS | 存在しないテーブルに対してもエラーを発生させず、警告のみを出力する。 スクリプトでの使用に適している。 |
| RESTRICT / CASCADE | MySQLでは機能せず、他のデータベースからの移植性のために用意されている。 |
使用例を以下に示す。
# 単一テーブルの削除
DROP TABLE users;
# 存在確認付きの削除
DROP TABLE IF EXISTS users;
# 複数テーブルの同時削除
DROP TABLE IF EXISTS users, orders, products;
# テンポラリテーブルの削除
DROP TEMPORARY TABLE temp_data;
IF EXISTS
IF EXISTS オプションは、テーブルが存在しない場合のエラーを防止する。
この機能は、データベースのマイグレーションスクリプトや初期化スクリプトで便利である。
# IF EXISTSなし : テーブルが存在しないとエラーになる
DROP TABLE users;
# ERROR 1051 (42S02): Unknown table 'database.users'
# IF EXISTSあり : テーブルが存在しなくても警告のみ
DROP TABLE IF EXISTS users;
# Query OK, 0 rows affected, 1 warning (0.00 sec)
TEMPORARY テーブル
TEMPORARY キーワードを使用することで、一時テーブルのみを削除対象にできる。
# 一時テーブルを作成
CREATE TEMPORARY TABLE temp_users (id INT, name VARCHAR(100));
# 一時テーブルのみを削除 (永続テーブルは削除されない)
DROP TEMPORARY TABLE temp_users;
# 永続テーブルとTEMPORARYテーブルが同名の場合
DROP TEMPORARY TABLE IF EXISTS users; # 一時テーブルのみ削除
DROP TABLE IF EXISTS users; # 永続テーブルを削除
RESTRICT と CASCADE
MySQLでは、RESTRICT および CASCADE オプションは定義されておらず、指定しても無視される。
これらは、他のデータベース管理システムとの互換性のために構文としてのみ許可されている。
# RESTRICTとCASCADEは記述可能だが、MySQLでは機能しない
DROP TABLE users RESTRICT;
DROP TABLE orders CASCADE;
DROP DATABASE
DROP DATABASE 文は、データベース全体を削除する。
データベース内の全てのテーブル、ビュー、ストアドプロシージャ、ファンクション、トリガー、イベントが削除される。
基本構文を以下に示す。
DROP DATABASE [IF EXISTS] database_name;
# または (SCHEMA は DATABASE のエイリアス)
DROP SCHEMA [IF EXISTS] database_name;
使用例を以下に示す。
# データベースの削除
DROP DATABASE myapp_db;
# 存在確認付きの削除
DROP DATABASE IF EXISTS myapp_db;
# SCHEMAキーワードを使用した削除
DROP SCHEMA IF EXISTS test_db;
DROP DATABASE は非常に危険な操作であるため、実行前に以下の確認を行う必要がある。
- 削除対象のデータベースが正しいかどうかを確認
SHOW DATABASES;またはSELECT DATABASE();で確認する。
- バックアップの取得
mysqldump等でバックアップを取得する。
- 外部キー制約の確認
- 他のデータベースから参照されていないか確認する。
DROP INDEX
DROP INDEX 文は、テーブルから指定したインデックスを削除する。
基本構文を以下に示す。
DROP INDEX index_name ON table_name;
# または ALTER TABLE を使用
ALTER TABLE table_name DROP INDEX index_name;
使用例を以下に示す。
# インデックスの削除
DROP INDEX idx_username ON users;
# IF EXISTS付きの削除 (MySQL 8.0.1以降)
DROP INDEX IF EXISTS idx_username ON users;
# ALTER TABLEを使用した削除
ALTER TABLE users DROP INDEX idx_username;
# PRIMARY KEYの削除
ALTER TABLE users DROP PRIMARY KEY;
# UNIQUE制約の削除
ALTER TABLE users DROP INDEX uk_email;
PRIMARY KEY制約 や UNIQUE制約として作成されたインデックスは、ALTER TABLE 文で削除する必要がある。
# PRIMARY KEYの削除 (DROP INDEXでは削除できない)
ALTER TABLE users DROP PRIMARY KEY;
# FOREIGN KEYの削除
ALTER TABLE orders DROP FOREIGN KEY fk_user_id;
DROP VIEW
DROP VIEW 文は、1つまたは複数のビューを削除する。
基本構文を以下に示す。
DROP VIEW [IF EXISTS] view_name [, view_name] ...;
使用例を以下に示す。
# ビューの削除
DROP VIEW user_profile;
# 存在確認付きの削除
DROP VIEW IF EXISTS user_profile;
# 複数ビューの同時削除
DROP VIEW IF EXISTS user_profile, order_summary, sales_report;
ビューを削除しても、ビューが参照している元のテーブルは影響を受けない。
ただし、削除したビューを参照している他のビューやストアドプロシージャは、実行時にエラーが発生する。
DROP PROCEDURE / DROP FUNCTION
DROP PROCEDURE 文 および DROP FUNCTION 文は、ストアドプロシージャとストアドファンクションを削除する。
基本構文を以下に示す。
DROP PROCEDURE [IF EXISTS] sp_name;
DROP FUNCTION [IF EXISTS] func_name;
使用例を以下に示す。
# ストアドプロシージャの削除
DROP PROCEDURE calculate_total;
DROP PROCEDURE IF EXISTS calculate_total;
# ストアドファンクションの削除
DROP FUNCTION get_user_age;
DROP FUNCTION IF EXISTS get_user_age;
# スキーマ名を指定した削除
DROP PROCEDURE mydb.calculate_total;
DROP FUNCTION mydb.get_user_age;
ストアドプロシージャとストアドファンクションを削除する場合は、ALTER ROUTINE 権限が必要である。
また、作成者は自動的に削除権限を持つ。
DROP TRIGGER
DROP TRIGGER 文は、指定したトリガーを削除する。
基本構文を以下に示す。
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name;
使用例を以下に示す。
# トリガーの削除
DROP TRIGGER update_user_timestamp;
# スキーマ名を指定した削除
DROP TRIGGER mydb.update_user_timestamp;
# 存在確認付きの削除
DROP TRIGGER IF EXISTS mydb.update_user_timestamp;
トリガーを削除するには、TRIGGER 権限が必要である。
トリガーが関連付けられているテーブルを削除すると、トリガーも自動的に削除される。
DROP EVENT
DROP EVENT 文は、スケジュールされたイベントを削除する。
基本構文を以下に示す。
DROP EVENT [IF EXISTS] event_name;
使用例を以下に示す。
# イベントの削除
DROP EVENT cleanup_old_data;
# 存在確認付きの削除
DROP EVENT IF EXISTS cleanup_old_data;
# スキーマ名を指定した削除
DROP EVENT mydb.cleanup_old_data;
イベントを削除するには、EVENT 権限が必要である。
イベントスケジューラが有効になっている場合、削除されたイベントは即座に実行停止される。
DROP USER
DROP USER 文は、1つまたは複数のMySQLユーザアカウントを削除する。
基本構文を以下に示す。
DROP USER [IF EXISTS] user [, user] ...;
ユーザ名の形式は、'<ユーザ名>'@'<ホスト名 または IPアドレス>' である。
使用例を以下に示す。
# ユーザの削除
DROP USER 'appuser'@'localhost';
# ワイルドカードホストのユーザを削除
DROP USER 'appuser'@'%';
# 存在確認付きの削除
DROP USER IF EXISTS 'appuser'@'localhost';
# 複数ユーザの同時削除
DROP USER IF EXISTS 'user1'@'localhost', 'user2'@'localhost';
DROP USER を実行すると、以下に示す情報が削除される。
- ユーザアカウント情報 (mysql.user テーブル)
- ユーザ名、ホスト、パスワード等の基本情報
- 権限情報 (mysql.db、mysql.tables_priv等)
- ユーザに付与されていた全ての権限
- ロール割り当て (MySQL 8.0以降)
- ユーザに割り当てられていたロール情報
DROP USER を実行するには、CREATE USER 権限 または mysql スキーマの DELETE 権限が必要である。
アクティブなセッションは削除されないため、現在接続中のユーザは接続が終了するまで操作を継続できる。
ただし、再接続時には削除された権限が適用される。
外部キー制約との関係
外部キー制約が設定されているテーブルを削除する場合、参照関係に注意が必要である。
親テーブル (参照される側) を削除しようとした場合、子テーブル (参照する側) が存在すると以下に示すようなエラーが発生する。
# 子テーブルから参照されている親テーブルの削除
DROP TABLE users;
# ERROR 1217 (23000): Cannot delete or update a parent row:
# a foreign key constraint fails
対処法を以下に示す。
方法1 : 削除順序を制御する
子テーブルを先に削除してから、親テーブルを削除する。
# 子テーブルを先に削除
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS order_items;
# その後、親テーブルを削除
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS products;
方法2 : FOREIGN_KEY_CHECKS を無効化する
一時的に外部キー制約のチェックを無効化して削除する。
# 外部キーチェックを無効化
SET FOREIGN_KEY_CHECKS = 0;
# テーブルを削除 (順序を問わない)
DROP TABLE parent_table;
DROP TABLE child_table;
# 外部キーチェックを再度有効化
SET FOREIGN_KEY_CHECKS = 1;
この方法は、一括削除やデータベースの初期化時に実行するとよい。
ただし、データの整合性が失われる可能性があるため、使用には注意が必要である。
DROP文の注意
復元不可能
DROP文で削除されたオブジェクトは、コミット後に復元することができない。
復旧はバックアップからのみ可能であるため、実行前に必ずバックアップを取得する必要がある。
# 削除前にバックアップを取得
mysqldump -u root -p mydb users > users_backup.sql
# テーブルを削除
DROP TABLE users;
# 復元 (バックアップから)
mysql -u root -p mydb < users_backup.sql
IF EXISTS の使用を推奨
スクリプトやマイグレーション処理では、IF EXISTS オプションを常に使用することが推奨される。
これにより、オブジェクトが存在しない場合でもスクリプトの実行が中断されない。
# 推奨 : IF EXISTSオプションを使用
DROP TABLE IF EXISTS users;
DROP DATABASE IF EXISTS myapp_db;
DROP VIEW IF EXISTS user_profile;
本番環境での実行
本番環境でDROP文を実行する場合は、以下の確認を行う必要がある。
- バックアップの取得
- 最新のバックアップが存在することを確認する。
- 削除対象の確認
SHOW TABLES;やSHOW DATABASES;で対象を確認する。
- 外部キー制約の確認
- 参照関係を確認し、削除順序を決定する。
- 影響範囲の確認
- 削除によって影響を受けるアプリケーションやユーザを確認する。
- メンテナンスウィンドウの設定
- 可能であれば、システム停止時間を設定する。
権限の確認
DROP文を実行するには、対象オブジェクトに対する適切な権限が必要である。
| オブジェクト | 必要な権限 |
|---|---|
| TABLE | DROP権限 |
| DATABASE | DROP権限 |
| INDEX | INDEX権限またはALTER権限 |
| VIEW | DROP権限 |
| PROCEDURE / FUNCTION | ALTER ROUTINE権限 |
| TRIGGER | TRIGGER権限 |
| EVENT | EVENT権限 |
| USER | CREATE USER権限 |
DROPとTRUNCATEとDELETEの違い
DROP文、TRUNCATE文、DELETE文の主な違いを以下に示す。
| 項目 | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| 分類 | DML (Data Manipulation Language) | DDL (Data Definition Language) | DDL (Data Definition Language) |
| データ削除 | 条件付き削除可能 | 全てのデータを削除 | 全てのデータを削除 |
| テーブル構造 | 保持される | 保持される | 削除される |
| WHERE句 | 使用可能 | 使用不可 | 使用不可 |
| トランザクションログ | 各行を記録 | 最小限の記録 | 最小限の記録 |
| トリガー発火 | DELETEトリガーが起動 | トリガーは起動しない | トリガーも削除される |
| AUTO_INCREMENT | 保持される | リセットされる | リセットされる |
| 処理速度 | 低速 (行単位処理) | 高速 (テーブル再作成) | 高速 (テーブル削除) |
| ロールバック | 可能 (コミット前) | 不可 (暗黙的コミット) | 不可 (暗黙的コミット) |
| 外部キー制約 | 制約に従う | 子テーブルがあるとエラー | 子テーブルがあるとエラー |
| 必要な権限 | DELETE権限 | DROP権限 | DROP権限 |
使い分けの指針を以下に示す。
- 条件付きでデータを削除する場合
- DELETE文を使用する。
- WHERE句で削除対象を指定できる。
- テーブルの全データを削除する場合
- TRUNCATE文を使用する。
- DELETE文より高速で、AUTO_INCREMENTがリセットされる。
- テーブル自体が不要になった場合
- DROP文を使用する。
- テーブル定義とデータが全て削除される。
使用例を以下に示す。
# DELETE : 条件付き削除
DELETE FROM logs WHERE created_at < '2024-01-01';
# TRUNCATE : 全データ削除 (高速)
TRUNCATE TABLE temp_data;
# DROP : テーブル自体を削除
DROP TABLE IF EXISTS temp_data;