SQLite | ゼロからはじめるSQL、30日で習得するSQLite:データ操作・設計 - Day17 削除

SQL SQLite
スポンサーリンク

Day17 前半

「本当に消える」DELETE は、UPDATE よりさらに“重い一手”

ここまでで、
SELECT(読む)
UPDATE(書き換える)
をやってきました。

Day17 のテーマは DELETE(削除)
名前の通り、テーブルから行を「消す」文です。

ここでまず、強く意識してほしいのはこれです。

UPDATE は「値を変える」なので、理屈の上では“再度 UPDATE すれば戻せる”可能性があります。
DELETE は「行そのものを消す」ので、実質的に“元に戻せない”操作 です(バックアップやトランザクションがなければ)。

だからこそ、
構文自体はシンプルなのに、
扱いは SQL の中でも最も慎重であるべき という存在です。

前半では、DELETE の基本形と、
「どこが危険ポイントなのか」を丁寧に押さえていきます。


DELETE の基本形

「どのテーブルから」「どの行を」消すかを指定する

DELETE の基本形はこうです。

DELETE FROM テーブル名
WHERE 条件;
SQL

UPDATE と同じく、
WHERE が“どの行を対象にするか”を決める唯一の場所 です。

例として、次の users テーブルを考えます。

id | name       | age
---+------------+----
 1 | 山田太郎   | 25
 2 | 佐藤花子   | 19
 3 | 鈴木一郎   | 30

ここで、「id=2 のユーザーを削除したい」とします。

DELETE FROM users
WHERE id = 2;
SQL

これで、id=2 の行だけがテーブルから消えます。


WHERE を書かない DELETE は“最悪の爆弾”

「テーブルの全行が消える」という、笑えない事故

UPDATE のときも話しましたが、DELETE はさらに危険です。

次のように書いたとします。

DELETE FROM users;
SQL

WHERE がありません。

この場合、
users テーブルの全行が削除されます。

「全削除したいときに使う構文」ではありますが、
初心者が一番やらかしやすい“事故 DELETE”でもあります。

しかも、UPDATE と違って、
「消えた行を UPDATE で戻す」ということはできません。

バックアップがなければ、
そのデータは事実上“永遠に失われる” と考えてください。

だからプロは、DELETE を打つときは必ず

同じ WHERE で SELECT して対象を確認する
本当に全削除したいとき以外、WHERE なし DELETE は絶対に書かない

という習慣を徹底しています。


DELETE 前に必ずやるべき“確認 SELECT”

「UPDATE と同じく、まずは“消える予定の行”を目で見る」

DELETE も UPDATE と同じく、
「先に SELECT で確認してから実行する」 が鉄則です。

例:

「age < 20 のユーザーを削除したい」とします。

いきなりこう書くのではなく、

SELECT * FROM users
WHERE age < 20;
SQL

で、「どの行が対象になるか」を目で確認します。

問題なければ、同じ条件で DELETE を実行します。

DELETE FROM users
WHERE age < 20;
SQL

さらに安全に行くなら、

SELECT COUNT(*) FROM users
WHERE age < 20;
SQL

で「何件消えるか」を事前に把握しておくのも有効です。

1件のつもりが 1000 件だった
0件のつもりが 50 件だった

といった違和感に気づけるからです。


条件付きで複数行を削除する

「古いデータをまとめて消す」「テストデータだけ消す」

DELETE は、1行だけでなく複数行をまとめて消すこともできます。

例:「20歳未満のユーザーを全員削除したい」

DELETE FROM users
WHERE age < 20;
SQL

例:「名前に『テスト』を含むユーザー(テストデータ)だけ削除したい」

DELETE FROM users
WHERE name LIKE '%テスト%';
SQL

ここでのポイントは、
WHERE の条件次第で、1行にも、100行にも、全行にもなり得る
ということです。

だからこそ、
「条件が本当に意図通りか?」を SELECT で確認する習慣が重要になります。


NULL を条件にした削除

「値が入っていない行だけを消す」

DELETE でも、NULL を条件にできます。

例:「メールアドレスが NULL のユーザーだけ削除したい」

DELETE FROM users
WHERE email IS NULL;
SQL

ここでも、
= NULL ではなく IS NULL を使う
という SQL のルールは変わりません。

実務では、

「必須項目が入っていない“壊れたデータ”だけを削除する」

といった用途で、NULL 条件の DELETE が使われることがあります。


セキュリティの視点から見る DELETE の重さ

「攻撃者に渡した瞬間、システムが“消される”可能性がある」

DELETE は、攻撃者にとっても“最強クラスの武器”です。

もしアプリケーションに SQL インジェクションの脆弱性があり、
そこから DELETE を自由に打てるとしたら、

全ユーザーを削除する
ログを削除して痕跡を消す
特定のユーザーだけを狙って消す

といったことが可能になります。

だからこそ、アプリ側では、

アプリケーションから実行できる SQL を厳しく制限する
プレースホルダを使って、ユーザー入力をそのまま SQL に埋め込まない
管理系の DELETE は、権限のある管理者だけに限定する

といった対策が必須です。

Day17 前半では、

「DELETE は、誤操作にも攻撃にも弱い“最も重い一手”」

という感覚だけ、しっかり持っておいてください。


小さな練習イメージ

頭の中で、次の日本語を SQL にしてみてください。

id=3 のユーザーを削除したい。
20歳未満のユーザーを全員削除したい。
メールアドレスが NULL のユーザーだけ削除したい。

どれも、

DELETE FROM テーブル名
WHERE 条件

という型に当てはめれば書けるはずです。


Day17 前半のまとめ

DELETE は「テーブルから行そのものを消す」文で、UPDATE よりもさらに不可逆性が高い。
WHERE を書かない DELETE はテーブル全行削除になり、最悪レベルの事故につながる。
DELETE の前には、必ず同じ WHERE で SELECT(+ COUNT)して対象と件数を確認するのが鉄則。
条件付き DELETE で、古いデータ・テストデータ・壊れたデータだけをまとめて消すことができる。
セキュリティの観点では、DELETE は攻撃者に絶対渡してはいけない“破壊権限”であり、アプリ側の制御が極めて重要。

後半では、
DELETE と外部キー制約(親子関係)の話、
論理削除(フラグ)と物理削除(DELETE)の使い分け、
「ログは消さない」「監査のために残す」という設計の考え方
などを扱って、より安全で現実的な「削除」との付き合い方を掘り下げていきます。

タイトルとURLをコピーしました