はじめに
SQLはデータベースを操作するための言語ですが、一歩間違えると大量のデータを削除したり、意図しない更新を行ってしまうことがあります。
特に本番環境では、一つのSQLがサービス全体に影響を与える可能性もあります。
この記事では、実務で特に慎重に扱うべきSQLと、安全に実行するためのポイントを紹介します。
1. DELETE(データ削除)
なぜ危険?
DELETEはデータを削除するSQLです。
最も多い事故は、WHERE句を書き忘れることです。
危険な例
DELETE FROM users;
このSQLを実行すると、usersテーブル内のすべてのデータが削除されます。
本来であれば
DELETE FROM users
WHERE id = 10;
のように削除対象を限定する必要があります。
安全に実行する方法
DELETEを実行する前に、同じ条件でSELECTを実行します。
SELECT *
FROM users
WHERE id = 10;
対象のデータが正しいことを確認してからDELETEを実行すると、事故を大きく減らせます。
2. UPDATE(データ更新)
なぜ危険?
UPDATEはデータを書き換えるSQLです。
こちらもWHEREを書き忘れる事故が非常に多くあります。
危険な例
UPDATE users
SET status = 'inactive';
このSQLでは、すべてのユーザーのstatusが変更されます。
正しくは
UPDATE users
SET status = 'inactive'
WHERE id = 10;
のように対象を限定します。
安全に実行する方法
UPDATEを実行する前に
SELECT *
FROM users
WHERE id = 10;
で対象データを確認する習慣を付けましょう。
3. DROP TABLE(テーブル削除)
なぜ危険?
DROP TABLEはテーブルそのものを削除します。
DROP TABLE users;
削除されるのはデータだけではありません。
- テーブル
- カラム
- 制約
すべて削除されます。
バックアップがなければ復旧できないケースもあります。
使用するタイミング
主に
- 開発環境
- テスト環境
で利用されます。
本番環境で実行することは非常に慎重な判断が必要です。
4. TRUNCATE TABLE(全件削除)
なぜ危険?
TRUNCATEはテーブルの中身をすべて削除します。
TRUNCATE TABLE users;
DELETEとの違いは、
- 非常に高速
- WHERE句を書けない
- 全件削除専用
という点です。
そのため、一度実行するとテーブル内のデータがすべて削除されます。
使用するタイミング
主に
- テストデータの削除
- 開発環境の初期化
などで使用されます。
5. ALTER TABLE(テーブル構造変更)
なぜ危険?
ALTER TABLEはテーブル構造を変更します。
例えば
ALTER TABLE users
DROP COLUMN email;
このSQLではemail列そのものが削除されます。
データだけではなく列自体がなくなるため、大きな影響があります。
使用するタイミング
- カラム追加
- カラム削除
- 型変更
など、データベース設計を変更するときに利用します。
UPDATE・DELETEで事故を防ぐコツ
① まずSELECTで確認する
更新や削除を行う前に、同じ条件でSELECTを実行します。
SELECT *
FROM users
WHERE id = 10;
対象データが正しいことを確認してからUPDATE・DELETEを実行しましょう。
② WHERE句を必ず確認する
実務では
「WHEREは付いているか?」
を必ず確認します。
レビューでも真っ先に見られるポイントです。
③ 一度に大量更新しない
一気に数万件更新するよりも、
- 少量更新
- 確認
- 本番実行
という流れの方が安全です。
④ トランザクションを利用する
更新前にトランザクションを開始すると、問題があれば元に戻せます。
BEGIN;
UPDATE users
SET status = 'inactive'
WHERE id = 10;
-- 内容を確認
ROLLBACK;
問題がなければ
COMMIT;
で変更を確定します。
実務での危険度
| SQL | 危険度 | 理由 |
|---|---|---|
| SELECT | ★☆☆☆☆ | データを取得するだけ |
| INSERT | ★★☆☆☆ | 不要なデータを追加する可能性 |
| UPDATE | ★★★★☆ | 大量更新の危険がある |
| DELETE | ★★★★★ | データを削除する |
| TRUNCATE | ★★★★★ | 全件削除する |
| DROP TABLE | ★★★★★ | テーブルごと削除する |
| ALTER TABLE | ★★★★☆ | テーブル構造を変更する |
実務では危険なSQLを誰でも実行できるの?
ここまで紹介したように、DELETE や DROP TABLE などのSQLは、大量のデータやテーブルそのものを削除できるため非常に危険です。
「こんな危険なSQLを誰でも実行できるの?」と思うかもしれませんが、実務ではデータベースの権限管理によって安全性が確保されています。
例えば、データベースにはユーザーごとに実行できる権限を設定できます。
| 権限 | できること |
|---|---|
| SELECT | データの取得 |
| INSERT | データの追加 |
| UPDATE | データの更新 |
| DELETE | データの削除 |
| ALTER | テーブル構造の変更 |
| DROP | テーブルの削除 |
そのため、本番環境では新人エンジニアやアプリケーション用のユーザーに、DROP や ALTER の権限を与えないケースも多くあります。
Spring Bootでも同様で、application.yml や application.properties に設定したデータベースユーザーの権限で接続します。
例えば、接続しているユーザーに DROP 権限がなければ、
DROP TABLE users;
を実行しても権限エラーとなり、処理は実行されません。
それでも事故が起こる理由
権限管理があるとはいえ、事故が完全になくなるわけではありません。
例えば、
-
UPDATEやDELETEのWHERE句を書き忘れる - 管理者権限を持つアカウントで誤って実行する
- 開発環境だと思って本番環境へ接続してしまう
といった人為的なミスによる事故は実際に発生しています。
そのため実務では、権限管理に加えて次のような対策も行われています。
- 更新・削除前に
SELECTで対象データを確認する -
WHERE句を必ず確認する - コードレビューを実施する
- トランザクションを利用する
- 本番作業前にバックアップを取得する
- 必要最小限の権限だけを付与する(最小権限の原則)
SQLは非常に強力な言語です。
そのため、SQLの書き方だけでなく、「安全に運用するための仕組み」が整えられていることも知っておくと、実務への理解がさらに深まるでしょう。
まとめ
SQLは便利ですが、更新系SQLは慎重に扱う必要があります。
特に実務では、次の3つを習慣にすると事故を大きく減らせます。
- UPDATE・DELETEの前にSELECTで対象データを確認する
- WHERE句が正しいか必ず確認する
- 本番環境ではトランザクションを活用する
SQLはデータベースを直接操作できる強力な言語です。
便利だからこそ、「正しく実行する」だけでなく「安全に実行する」という意識を持つことが、実務では非常に重要になります。