やあ。PostgreSQLの世界へようこそ。
今日は、SQLの基本中の基本、いわゆる「DML(データ操作言語)」の話をしよう。INSERT、UPDATE、DELETE。この3つがなければ、データベースはただの「動かない辞書」でしかない。
教科書的な構文はドキュメントを見れば誰でもわかる。でも、現場で「事故らない」ための作法や、トランザクションとの付き合い方を肌感覚で理解しているかどうかが、エンジニアとしての格を分けるんだ。
少しだけ、現場の知恵を共有させてくれ。
—
1. INSERT:まずは基本、でも「一括」を意識しよう
まずはデータの挿入だ。基本はこう書くよね。
INSERT INTO users (name, email, created_at)
VALUES (‘Tanaka’, ‘tanaka@example.com’, CURRENT_TIMESTAMP);
ここで一つアドバイス。実務で1件ずつループでINSERTを投げるのは、ネットワークの往復コストがかかって効率が悪い。もし大量のデータを流し込むなら、`VALUES`をカンマで繋いで一括挿入する癖をつけよう。
INSERT INTO users (name, email)
VALUES
(‘Alice’, ‘alice@example.com’),
(‘Bob’, ‘bob@example.com’),
(‘Charlie’, ‘charlie@example.com’);
これだけでパフォーマンスは劇的に変わる。あと、`RETURNING`句を使うのもおすすめだ。「挿入した後のIDをすぐ使いたい」なんて時に、わざわざ`SELECT`し直さなくて済むからね。
INSERT INTO users (name) VALUES (‘Dave’) RETURNING id;
—
2. UPDATE:WHERE句を忘れるのは「死」を意味する
UPDATEで一番怖いのは何だと思う? そう、「条件を書き忘れてテーブル全件を更新してしまう」ことだ。
PostgreSQLは親切じゃない。`WHERE`がないUPDATEを実行しても、エラーを吐かずに静かに全件書き換えてしまう。
— これをやると、全ユーザーのメールアドレスが同じになる(大惨事)
UPDATE users SET email = ‘hacked@example.com’;
対策:
1. 必ず先に`SELECT`する: 更新対象が意図通りか、まずは`SELECT`で確認する。これが鉄則だ。
2. トランザクションを明示する: `BEGIN;` を忘れずに。
—
3. DELETE:データは消すより「見えなくする」のが安全
DELETEは、実は現場ではあまり使わない。物理的に消すと復旧が大変だし、参照整合性(外部キー)でエラーになることも多いからね。
最近の主流は「論理削除」だ。`is_deleted` というフラグを持たせて、`UPDATE`でフラグを立てる手法だね。
— 物理削除ではなく論理削除
UPDATE users SET is_deleted = true WHERE id = 101;
もし物理的に`DELETE`する場合も、必ず`WHERE`句を確認すること。そして、もし数万件以上のデータを消すなら、トランザクションが長くなりすぎてDB全体のロックを長時間握ってしまうリスクがあることを覚えておいてほしい。
—
4. 忘れてはいけない「トランザクション」という防波堤
最後に、これが一番大事な話だ。
PostgreSQLは、すべてのSQLが暗黙的にトランザクションの中で実行されている。でも、複数の操作を一つの塊として成功させたい場合は、必ず明示的に囲おう。
BEGIN;
INSERT INTO logs (action) VALUES (‘update_user’);
UPDATE users SET name = ‘New Name’ WHERE id = 1;
COMMIT;
もし途中でエラーが起きたら、`ROLLBACK`すれば元のクリーンな状態に戻る。この「巻き戻せる」という安心感こそが、PostgreSQLを信頼して使う理由なんだ。
最後に:先輩からのアドバイス
エンジニアとして腕を上げたいなら、クエリを書く前に「もしこれが本番環境の、数百万件あるテーブルだったらどうなるか?」を常に想像してみてほしい。
- このUPDATEでロックはどれくらいかかる?
- インデックスは効いているか?
- 失敗したとき、どうやってリカバリする?
この視点を持つだけで、君が書くコードの質は格段に上がるはずだ。
次はインデックスの話でもしようか。あれを知ると、SQLがまた一段と面白くなるぞ。またいつでも聞いてくれ。
コメント