MySQLのINSERT、DELETE、UPDATE操作に関する詳細な解説
データの挿入、更新、削除はデータベースの基本操作であり、INSERT、UPDATE、DELETE は DML の核心をなすものです。
このレッスンでは、データの挿入、更新、削除の方法について体系的に解説します。
graph TB
A[DML Operation] --> B[INSERT Insert]
A --> C[UPDATE Update]
A --> D[DELETE Delete]
B --> B1[Single-row insertion]
B --> B2[Multi-line Insertion]
B --> B3[Subquery Insertion]
B --> B4[UPSERT]
C --> C1[Conditional Update]
C --> C2[JOIN Update]
D --> D1[Conditional Deletion]
D --> D2[TRUNCATE Clear]
1. 学習内容
- INSERT:1行、複数行、およびサブクエリによる挿入
- 更新:状況の更新
- 条件付きDELETE
- TRUNCATE:テーブルの内容をすべて削除する
- 重複キー時の挿入・更新
2. 実話
(1) 課題:データを手作業で一つずつ入力するのは、極めて非効率的である
在庫管理システムでは、1日あたり10,000件以上のデータ書き込み処理が行われています。運用担当者はINSERTやUPDATE操作を1件ずつ手作業で行っていますが、これは極めて非効率であるだけでなく、コピー&ペーストのミスによるデータ破損も頻繁に発生しています。一括価格調整の際、UPDATE文を1件ずつ実行するのに3時間かかりましたが、その間に担当者が誤って間違ったWHERE句を入力してしまい、テーブル全体の価格がすべて0に設定されてしまいました。
(2) バッチ処理とトランザクションを組み合わせた解決策
バッチINSERT、トランザクション処理によるUPDATE、および条件付きDELETEをINSERT ON DUPLICATE KEY UPDATEと組み合わせて使用し、すべてのデータを単一の操作で処理します。
| 次元 | 個別操作 | バッチ処理 + トランザクション |
|---|---|---|
| 書き込み 10,000 回 | 約 3 時間 | 約 3 分 |
| エラーのリスク | 高(人為的ミスが発生しやすい) | 低(トランザクション保護) |
| ネットワークの往復回数 | 10,000 | 1 |
| 速度向上 | — | 50倍 |
3. INSERT:データの挿入
▶ 例:1行の挿入
SQL
-- Insert in Full
INSERT INTO users (username, email, age)
VALUES ('alice', 'alice@email.com', 25);
-- Omit field names(Must be in order)
INSERT INTO users VALUES (1, 'bob', 'bob@email.com', 30);
▶ 例:複数行の挿入
SQL
INSERT INTO products (name, price, category) VALUES
('iPhone', 999, 'Phone'),
('MacBook', 1999, 'Laptop'),
('iPad', 599, 'Tablet');
▶ 例:サブクエリの挿入
SQL
-- Insert from Query Results
INSERT INTO user_archive (id, name, email)
SELECT id, name, email FROM users WHERE status = 'deleted';
4. UPDATE:データの更新
▶ 例:条件付き更新
SQL
-- Update a Single Record
UPDATE users SET email = 'new@email.com' WHERE id = 1;
-- Update Multiple Records
UPDATE products SET price = price * 1.1 WHERE category = 'Electronics';
-- Multi-Field Update
UPDATE users SET age = age + 1, status = 'active' WHERE id = 1;
▶ 例:UPDATE + JOIN
SQL
-- Related Updates
UPDATE orders o
INNER JOIN customers c ON o.customer_id = c.id
SET o.status = 'priority'
WHERE c.level = 'VIP';
5. DELETE:データの削除
▶ 例:条件付き削除
SQL
-- Delete a Single Record
DELETE FROM users WHERE id = 1;
-- Delete Multiple Records
DELETE FROM orders WHERE status = 'cancelled' AND created_at < '2025-01-01';
-- Deleting Related Records
DELETE o FROM orders o
INNER JOIN customers c ON o.customer_id = c.id
WHERE c.status = 'banned';
(1) TRUNCATE と DELETE の違い
| ディメンション | TRUNCATE | DELETE |
|---|---|---|
| 速度 | 非常に速い | 遅い |
| トランザクション | ロールバックなし | ロールバック |
| トリガー | トリガー未発動 | トリガー発動 |
| AUTO_INCREMENT | リセット | リセットしない |
| 場所 | 未対応 | 対応 |
SQL
-- Clear the table (Non-rollbackable)
TRUNCATE TABLE temp_data;
6. 重複キー時のINSERTおよびUPDATE
主キーまたは一意キーの競合がある場合は、更新を実行してください。
▶ 例:UPSERT 操作
SQL
-- Insert or Update
INSERT INTO product_stats (product_id, view_count, last_viewed)
VALUES (1, 1, NOW())
ON DUPLICATE KEY UPDATE
view_count = view_count + 1,
last_viewed = NOW();
-- Batch UPSERT
INSERT INTO user_scores (user_id, score) VALUES
(1, 100), (2, 200), (3, 300)
ON DUPLICATE KEY UPDATE
score = VALUES(score);
7. REPLACE INTO
(競合が発生した場合は)まず削除してから、挿入してください。
▶ 例:REPLACE
SQL
-- Replace if it exists, insert if it doesn't
REPLACE INTO users (id, username, email)
VALUES (1, 'alice_updated', 'alice_new@email.com');
⚠️ 注意: REPLACE文は、古い行を削除してから新しい行を挿入するため、DELETEトリガーとINSERTトリガーの両方が発動し、AUTO_INCREMENTの値も変更されます。
8. 安全ガイドライン
| アクション | 推奨事項 |
|---|---|
| UPDATE/DELETE | WHERE 句を必ず指定する必要があります。まず SELECT を使用して、操作の範囲を確認してください |
| 一括処理 | 1,000~5,000行ずつバッチ処理で実行 |
| 本番環境 | トランザクションを開始し、確認後にCOMMITを実行する |
| バックアップ | 操作前 mysqldump バックアップ |
▶ 例:セキュリティ更新のプロセス
SQL
-- 1. Check and confirm first
SELECT COUNT(*) FROM orders WHERE status = 'cancelled' AND created_at < '2025-01-01';
-- 2. Start a transaction
START TRANSACTION;
-- 3. Execute Delete
DELETE FROM orders WHERE status = 'cancelled' AND created_at < '2025-01-01';
-- 4. Submit after verifying that everything is correct
COMMIT;
-- Or roll back if a problem is detected
-- ROLLBACK;
❓ よくある質問
Q INSERT文のフィールド順は、テーブル定義と一致させる必要がありますか?
A フィールド名が省略されている場合にのみ、一致させる必要があります。順序に依存しないように、フィールド名を明示的に指定することをお勧めします。
Q DELETE 実行後にデータを復元することはできますか?
A トランザクション内であれば ROLLBACK を行うことができます。COMMIT 済みのデータについては、バックアップから復元する必要があります。TRUNCATE はロールバックできません。
Q 一括INSERT操作を最適化するにはどうすればよいですか?
A 複数行のVALUESを使用し、自動コミットを無効にし、インデックスを無効にし、LOAD DATA INFILEを使用してください。
Q INSERT と REPLACE の違いは何ですか?
A INSERT は一意キーの競合が発生するとエラーを返しますが、REPLACE は新しいレコードを挿入する前に既存のレコードを削除します(ID は変更されます)。ON DUPLICATE KEY UPDATE の使用をお勧めします。
Q DELETE と TRUNCATE の違いは何ですか?
A DELETE は行を1つずつ削除し、ロールバックが可能ですが、TRUNCATE はテーブルの内容をすべて削除し、ロールバックはできませんが、処理が極めて高速です。
📖 まとめ
- INSERT データの挿入。単一行、複数行、およびサブクエリに対応しています。
- 更新 データを更新するには、WHERE句を指定する必要があります
- DELETE データを削除します。WHERE句を必ず指定する必要があります。
- TRUNCATE テーブルの内容をすべて削除します。処理は高速ですが、ロールバックすることはできません。
- INSERT ON DUPLICATE KEY UPDATE は UPSERT を実装しています
- 操作を実行する前に必ず確認してください。本番環境ではトランザクション保護を使用してください。
📝 練習問題
-
基本問題(難易度 ⭐):
usersテーブルに 5 件のテストレコードを挿入してください。 -
上級問題(難易度:⭐⭐):
INSERT ON DUPLICATE KEY UPDATEを使用して訪問回数のカウンターを実装してください。 -
課題(難易度:⭐⭐⭐):トランザクション保護機能を使用して、30日前に作成された一時データを安全に削除するスクリプトを作成してください。



