データベース管理において、不要になったデータを削除する操作は避けては通れません。MySQLでは、DELETE文を使うことで、特定の条件に一致するデータを削除することができます。しかし、使い方を誤ると重要なデータを失ってしまう危険性もあるため、慎重に扱う必要があります。この記事では、MySQLにおけるDELETE文の基本的な使い方から、複雑な条件付き削除、パフォーマンスへの影響、安全に運用するためのベストプラクティスまで、幅広く解説していきます。
DELETE文の基本構文
MySQLにおけるDELETE文の基本的な構文は以下の通りです。
DELETE FROM テーブル名 WHERE 条件;
この文法は、テーブル名
に指定したテーブルから、WHERE
句の条件に合致する行を削除するものです。たとえば、users
テーブルから特定のIDのユーザーを削除したい場合は、次のように記述します。
DELETE FROM users WHERE id = 5;
重要なのは、WHERE句を省略するとすべての行が削除される点です。以下のようなSQLを実行すると、テーブル内の全データが消去されるので注意が必要です。
DELETE FROM users;
DELETEとTRUNCATEの違い
MySQLにはデータ削除に関して、DELETE
の他にTRUNCATE
文もあります。一見似ていますが、両者には以下のような違いがあります。
比較項目 | DELETE | TRUNCATE |
---|---|---|
WHERE句 | 使用可能 | 使用不可 |
ログへの記録 | 行単位で記録(遅い) | テーブル単位(高速) |
AUTO_INCREMENT | 変化しない | 初期化される |
トリガー | 発動する | 発動しない(バージョン依存) |
テーブル内の一部データのみを削除したい場合はDELETEを、全データを高速に削除したい場合はTRUNCATEを使うのが基本です。
複数条件を指定してDELETEする
DELETE文では、複数の条件を組み合わせて削除対象を絞ることができます。
DELETE FROM users
WHERE age < 18 AND country = 'Japan';
このSQL文は、18歳未満かつ日本に住んでいるユーザーのみを削除します。
条件を絞りすぎたり、逆に漏れがあると意図しないデータが削除される可能性があるため、実行前にはSELECT
文で対象データを確認することが推奨されます。
SELECT * FROM users
WHERE age < 18 AND country = 'Japan';
削除対象をLIMITで制限する
DELETE文では、LIMIT
句を使って削除する行数を制限することも可能です。大量のデータを一度に削除するとロックが発生しやすいため、段階的に削除したいときに便利です。
DELETE FROM logs
ORDER BY created_at ASC
LIMIT 1000;
この文では、logs
テーブルの中から、もっとも古いデータを1000件削除します。定期的にバッチ処理で古いデータを削除したい場合などに使えます。
DELETEとJOINを組み合わせる
MySQLでは、他のテーブルとJOINして条件を指定しながらDELETEすることも可能です。たとえば、退会済みのユーザーのコメントを削除する場合は以下のようにします。
DELETE comments FROM comments
JOIN users ON comments.user_id = users.id
WHERE users.deleted_at IS NOT NULL;
このように、JOINを活用することで、関連データに基づいた削除が実現できます。
外部キー制約とDELETE
外部キー制約(FOREIGN KEY)が設定されているテーブルでは、親テーブルのデータを削除するときに注意が必要です。
DELETE FROM users WHERE id = 1;
このような操作をすると、users
テーブルを参照しているorders
テーブルなどに外部キー制約がある場合、削除に失敗することがあります。これを防ぐには、以下のようにCASCADEを利用して、関連データも同時に削除することができます。
ALTER TABLE orders
ADD CONSTRAINT fk_user_id
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE;
DELETE文のパフォーマンスに注意
DELETE文は、件数が多くなるとパフォーマンスに影響が出ることがあります。以下のような対策が考えられます。
- インデックスを適切に設定しておく
- WHERE句で絞り込み条件を明確にする
- LIMITを使って段階的に削除する
- トランザクションを使って途中で止められるようにする
大量のデータ削除を伴う作業は、システムの負荷が少ない時間帯に行うようにしましょう。
トランザクションで安全に削除
誤ってDELETE文を実行してしまった場合、取り返しがつかないことがあります。これを防ぐには、トランザクションを活用して、一連の処理を確認後に確定するようにすると安全です。
START TRANSACTION;
DELETE FROM users WHERE id = 99;
-- 確認
SELECT * FROM users WHERE id = 99;
-- 問題なければ
COMMIT;
-- 問題があれば
-- ROLLBACK;
ROLLBACK
を実行すれば、削除前の状態に戻すことが可能です。
まとめ:DELETEは慎重に、確認を怠らずに
MySQLのDELETE文は非常に強力なコマンドであり、操作を誤ると貴重なデータを一瞬で失う可能性があります。しかし、適切に条件を指定し、必要に応じてトランザクションやLIMITを併用すれば、安全に運用することが可能です。
削除対象のデータを事前にSELECTで確認すること、外部キー制約を理解しておくこと、そして本番環境でのDELETE操作は極力バックアップを取ってから行うことを習慣づけましょう。