プログラミングスクール デイトラ 全コース10000円OFF 8/31日まで

SQLで「データを入れる・直す・消す」をしっかり理解する

5 min 14 views
SQL DELETEなど

―― INSERT / UPDATE / DELETE とトランザクションの世界 ――

前回は「SQLでデータを検索する方法」についてお話しました。

検索ができるようになると、データベースの世界が一気に開けますよね。

でも実際のシステムは「見る」だけで完結しません。

ユーザーが新しく登録したり、間違えた情報を修正したり、もう不要になったデータを消したり…日常的に「データを変える作業」が発生します。

この「変える作業」を担うのが、SQLの三大コマンドといってもいい INSERT(追加)、UPDATE(変更)、DELETE(削除) です。

どれも非常に強力で便利ですが、そのぶん一歩間違えると取り返しがつかない事故につながります。

たとえば、「DELETE文をWHERE句なしで実行してしまい、全データが消えた」なんて話は、データベースを触る人なら一度は耳にしたことがあるでしょう。

そこでこの記事では、ただの文法解説に留まらず、実務で本当に気をつけるべきことや運用の知恵を交えて丁寧に説明します。

まずは「追加」です。

人間でいえば「新しく誰かが名簿に加わる」イメージですね。

INSERT INTO users (email, name)
VALUES ('taro@example.com', 'Taro');

たったこれだけで、新しい人がテーブルに仲間入りします。

ただし、INSERT文は「どの列に、どんなデータを入れるのか」をきちんと指定するのが基本。

列リストを省略してしまうと、後でテーブル定義が変わったときに大事故を起こす可能性があるんです。

また、現場でよく出てくるのは「複数人を一気に登録したい」というケース。

INSERT INTO users (email, name) VALUES
('hanako@example.com', 'Hanako'),
('jiro@example.com',   'Jiro');

これでまとめて追加できます。

大量データを扱うときは、この形を覚えておくとパフォーマンスが段違いに上がります。

さらに実務的に便利なのが、「もしすでに存在していたらどうするか」というパターン

たとえばメールアドレスはユニーク制約をつけていることが多いので、既存のアドレスをもう一度INSERTするとエラーになってしまいます。

そこで使うのが ON DUPLICATE KEY UPDATE です。

INSERT INTO users (email, name)
VALUES ('jiro@example.com', 'Jiro')
ON DUPLICATE KEY UPDATE
  name = VALUES(name),
  updated_at = NOW();

これで「新規なら登録、存在していたら更新」とスマートに切り替えられる。まさに現場向けの技です。

次は「修正」です。

会員登録時に「Hanako」を「Hanak」と間違えてしまった。こんなときに活躍するのがUPDATE。

UPDATE users
SET name = 'Hanako'
WHERE id = 2;

ただし、ここで絶対に忘れてはいけないのが WHERE句

これを忘れると、テーブル全員の名前が「Hanako」に変わる…という悲劇が起こります。

実務では、次のようにPK(主キー)やユニークキーでピンポイントに対象を絞るのが鉄則です。

UPDATE users
SET name = 'Hanako Y.'
WHERE email = 'hanako@example.com';

また、UPDATEは単純な置き換えだけではなく「計算式」も書けます。

UPDATE stocks
SET quantity = quantity - 1,
    updated_at = NOW()
WHERE sku = 'ABC-001';

在庫数を減らすと同時に、更新時刻も記録。これなら一貫性が保たれますね。

そして最後は「削除」。

DELETE FROM users WHERE id = 3;

シンプルですが、やはり注意が必要。DELETE文で一番怖いのはWHEREを書き忘れることです。

安全策としては

  • LIMITを使って少しずつ削除する
  • 削除前にSELECTで対象を確認する
  • 本当に消すのではなく「論理削除(フラグを立てる)」を検討する

たとえば論理削除はこんな感じです。

ALTER TABLE users ADD COLUMN deleted_at DATETIME NULL;

UPDATE users
SET deleted_at = NOW()
WHERE id = 5;

こうしておけば、後で「やっぱり復活させたい」というときにも対応できます。

実際、多くのWebサービスではこの「論理削除」が採用されています。

今思い出したのですが、スタアカでデータ分析でのSQLが習えます。わかりやすいし安いしおススメです。

ここまでで「追加・修正・削除」ができるようになりました。

ただ、現実のシステムはこれらを一連の流れとしてまとめて処理する必要があります。

たとえばECサイトでの「注文処理」。

  1. 注文テーブルに新しいレコードをINSERT
  2. 在庫数をUPDATEして減算
  3. 履歴テーブルにINSERT

この途中でエラーが起きたらどうなるでしょう?

在庫だけ減って、注文が残らない…そんな不整合が起きてしまいます。

ここで登場するのが トランザクション です。

START TRANSACTION;

INSERT INTO orders (...);
UPDATE stocks SET quantity = quantity - 1 WHERE ...;
INSERT INTO order_logs (...);

COMMIT; -- すべて成功したら確定
-- エラーが出たら ROLLBACK;

トランザクションは「全部まとめて成功するか、まとめて失敗にするか」を保証してくれる仕組み。

だから安心して複数の操作を連続して行えるんですね。

よく教科書で「トランザクションはACID特性を持つ」と書かれていますが、ここを“人の行動”に例えてみましょう。

  • Atomicity(原子性)
    → 「やるか、やらないか」。結婚式で「指輪交換」だけして「誓いの言葉」はスキップ、なんてあり得ませんよね。全部まとめて完了するか、なかったことにするか。
  • Consistency(一貫性)
    → 「ルールは守る」。借金残高がマイナスになったり、存在しない商品に注文を入れたりしてはいけません。
  • Isolation(隔離性)
    → 「お互いに干渉しない」。レジに並んでいる人が同じ商品を同時に取ろうとしたら混乱しますよね。順番を守って整合性を保つ。
  • Durability(耐久性)
    → 「確定したら消えない」。契約書にハンコを押したら、雷が落ちても記録は残る。これがデータベースの「永続性」です。

こう考えると、ACIDもぐっと身近に感じられるはずです。

トランザクションで大事なのが「ロック」。

たとえばスーパーでレジ待ちをしているときに、誰かが割り込んできたら大混乱ですよね。

データベースも同じで、今誰がどの行を使っているのか、ルールを守らないとケンカ(競合)が起きます

さらに怖いのは デッドロック

これは「AさんがBさんの本を借りたい、BさんはAさんの本を借りたい」でお互い譲らず、ずっと動けなくなる状態。

データベースは「仕方ない、どちらかを強制的に諦めさせよう」と判断して、一方のトランザクションをロールバックさせます

現場での鉄則は:

  • 更新の順番を統一する
  • トランザクションは短くする
  • デッドロックは「起きない」ではなく「起きる前提でリトライ処理を書く」

こういう割り切りがプロの知恵です。

最後に、もしデータベースに障害が起きたらどうなるのか。

  • ハードウェア障害:サーバーのディスクが壊れた
  • ソフトウェア障害:アプリのバグで異常終了
  • システム障害:停電でOSごと落ちた

こうしたときに、トランザクションやログのおかげで「コミット済みのデータはちゃんと残る」「未完了のデータは巻き戻される」ようになっています。

さらに、定期的なバックアップとバイナリログを使えば「昨日の17時時点まで復元」といった芸当も可能。

つまりデータベースは、私たちが安心して使えるように二重三重の守りを持っているわけです。

ここまで「INSERT・UPDATE・DELETE」という基本操作から、トランザクション、ACID特性、ロックやデッドロック、そして障害対応まで、実務で欠かせない知識をひと通り整理しました。

  • データを変えるときは常にWHERE句の意識を忘れない
  • トランザクションで一貫性を守る
  • ロックとデッドロックは人間関係と同じ、順序と譲り合いが大事
  • 万一に備えてバックアップと復旧手順を整える

これらを意識するだけで、SQL操作が一気に安心・安全になります。

ガッツリ習いたい人はここ

関連記事