ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|---|
|
基本構文
-- 在庫を 10 個加算
UPDATE products
SET stock = stock + 10
WHERE id = 1;
-- ポイントを 100 ポイント加算
UPDATE users
SET points = points + 100
WHERE id = 123;
-- 売上を 1000 円加算
UPDATE sales
SET amount = amount + 1000
WHERE date = CURRENT_DATE;
各 DB での書き方
| DB | 構文 |
|---|---|
| MySQL | UPDATE t SET col = col + N WHERE ... |
| PostgreSQL | 同上 |
| Oracle | 同上 |
| SQL Server | 同上 |
| SQLite | 同上 |
応用例
① 複数列を同時加算
UPDATE users
SET
points = points + 100,
total_purchases = total_purchases + 1,
last_purchased_at = CURRENT_TIMESTAMP
WHERE id = 1;
② 別テーブルの値を加算
-- MySQL / PostgreSQL
UPDATE users u
SET points = u.points + (SELECT bonus FROM events WHERE id = 5)
WHERE u.id = 1;
-- JOIN を使う書き方 (MySQL)
UPDATE users u
INNER JOIN event_bonuses eb ON u.id = eb.user_id
SET u.points = u.points + eb.bonus_amount
WHERE eb.event_id = 5;
③ 条件式で動的に加算量を変える
-- ランクで加算量を変える
UPDATE users
SET points = points + CASE
WHEN rank = 'GOLD' THEN 500
WHEN rank = 'SILVER' THEN 200
ELSE 100
END
WHERE active = 1;
④ 上限を超えないようにする
-- 在庫上限 100 を超えないように
UPDATE products
SET stock = LEAST(stock + 10, 100)
WHERE id = 1;
-- 0 以下にならないように(減算時)
UPDATE products
SET stock = GREATEST(stock - 10, 0)
WHERE id = 1;
⑤ NULL を考慮(COALESCE)
-- NULL の場合は 0 として加算
UPDATE users
SET points = COALESCE(points, 0) + 100
WHERE id = 1;
-- 初期値もセット
UPDATE users
SET points = COALESCE(points, 0) + 100,
points_updated_at = CURRENT_TIMESTAMP
WHERE id = 1;
競合状態(Race Condition)と対策
複数トランザクションが同時に同じ行を加算しようとすると更新ロストが起きる可能性:
-- トランザクション A: stock = 100 → 100 + 10 = 110
-- トランザクション B: stock = 100 → 100 + 5 = 105 (A の更新を見ない)
-- 最終的に 105 になり、A の +10 が失われる可能性
-- 対策 1: 行レベルロック (SELECT FOR UPDATE)
BEGIN;
SELECT stock FROM products WHERE id = 1 FOR UPDATE; -- ロック取得
-- ここで取得した値を元に計算
UPDATE products SET stock = stock + 10 WHERE id = 1;
COMMIT;
-- 対策 2: 単純な UPDATE はアトミック(推奨)
UPDATE products SET stock = stock + 10 WHERE id = 1;
-- 行レベルロックが自動的に取得される
-- 同時 UPDATE は順次実行される
-- ただし結果が想定通りかは別問題(後述の楽観ロック)
楽観ロック(@Version)
「更新前と更新後で別のトランザクションが書き換えていたら失敗扱いにする」方式:
-- バージョン番号を併用
UPDATE products
SET stock = stock + 10,
version = version + 1
WHERE id = 1 AND version = 5; -- 期待バージョン
-- 影響行数が 0 なら他のトランザクションが先に更新 → リトライ
-- JPA + @Version で自動化される
大量カウンタは別の仕組みを検討
「PV カウント」「いいね数」のような高頻度更新は SQL の UPDATE では性能不足:
① Redis INCR
# Redis (キー1つあたり 数万 ops/s)
INCR page_view:article:123
INCRBY user_points:1 100
DECR stock:product:1
# Redis → 定期的に DB へ flush
② 別カウンタテーブル(バッチ集計)
-- イベント追記 (高速、競合なし)
INSERT INTO point_events (user_id, points, created_at)
VALUES (1, 100, NOW());
-- 集計はバッチで
UPDATE users u
SET points = u.points + (
SELECT SUM(points) FROM point_events
WHERE user_id = u.id AND processed = 0
);
UPDATE point_events SET processed = 1 WHERE processed = 0;
ORM (Java JPA) で加算
// 通常のエンティティ更新
@Transactional
public void addPoints(Long userId, int amount) {
User user = userRepository.findById(userId).orElseThrow();
user.setPoints(user.getPoints() + amount);
// Dirty Checking で UPDATE が自動発行
}
// バルク UPDATE (高速)
@Modifying
@Query("UPDATE User u SET u.points = u.points + :amount WHERE u.id = :id")
int addPointsBulk(@Param("id") Long id, @Param("amount") int amount);
// 楽観ロック
@Entity
public class User {
@Id private Long id;
private int points;
@Version
private Long version; // ← 自動でインクリメント、競合検出
}
注意点
- 初期値 NULL: NULL + 数値 = NULL なので COALESCE が必要
- オーバーフロー: INT 範囲(21億)を超える可能性は BIGINT に変更
- マイナス値: 負の数で加算 = 減算、上限 / 下限を CHECK 制約で守る
- トリガとの干渉: AFTER UPDATE トリガで集計値が二重カウントされないか確認
- Read After Write 整合性: 加算直後の SELECT で最新値を得るには同トランザクション内で実行
関連記事
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Laravel キャッシュクリア完全ガイド(cache:clear / config:clear / 2026-05-18 07:42:07
- プロジェクトの作成と削除 2026-05-18 07:42:07
- インストール直後にNetbeansが反応しない 2026-05-18 07:42:07
- 動画やチャンネルの検索 2026-05-18 07:42:07
- APIキー取得方法 2026-05-18 07:42:07
- チャンネル情報の取得 2026-05-18 07:42:07
- API 入門 — Web API(REST / GraphQL / gRPC / 2026-05-18 07:42:07
- インストール(eclipseプラグイン) 2026-05-18 07:42:07
- Laravel「Dotenv values containing spaces must be surrounded 2026-05-18 07:42:07
- エラー一覧 2026-05-18 07:42:07
- curl: (51) SSL: certificate subject name '~' does not match 2026-05-18 07:42:07
- インストール方法(Windows版) 2026-05-18 07:42:07
- JSONから配列に変換 2026-05-18 07:42:07
- 処理を一定時間待つ 2026-05-18 07:42:07
- A non well formed numeric value encountered 2026-05-18 07:42:07
コメントを削除してもよろしいでしょうか?