You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免INSERT ... ON DUPLICATE KEY UPDATE导致自增ID持续增长?

问题分析与解决方案

你遇到的核心问题是INSERT...ON DUPLICATE KEY UPDATE没有触发更新逻辑,反而每次都执行插入操作,导致自增ID持续增长,根源和解决方法如下:

根本原因

你的race_id字段没有设置主键或唯一约束,MySQL无法识别重复的race_id,因此不会触发ON DUPLICATE KEY UPDATE分支,每次都会执行INSERT生成新行,自增ID自然随之增加。另外,你的代码直接拼接变量到SQL中,存在严重的SQL注入风险。


具体解决步骤

1. 给race_id添加唯一约束

首先修改表结构,让MySQL能够识别重复的race_id:

-- 方案1:给race_id添加唯一约束(适合race_id不是主键的场景)
ALTER TABLE webpage_race ADD UNIQUE KEY idx_race_id (race_id);

-- 方案2:将race_id设为主键(如果它本身是记录的唯一标识)
ALTER TABLE webpage_race MODIFY COLUMN race_id INT PRIMARY KEY;

2. 修正PHP代码逻辑并修复SQL注入

改用预处理语句避免注入,同时优化ON DUPLICATE KEY UPDATE的逻辑(更新race_id为自身无意义,仅作为占位触发不插入新行即可):

<?php
foreach($race_obj as $key => $race_value){
    $race_id = $race_value->race_id ?? null;

    // 跳过空的race_id记录(如果race_id不允许为null)
    if(is_null($race_id)){
        echo '<p align="center">跳过空race_id的记录<br>';
        continue;
    }

    // 使用预处理语句,避免SQL注入
    $sql = '
        INSERT INTO webpage_race (race_id)
        VALUES (?)
        ON DUPLICATE KEY UPDATE
            race_id = race_id -- 占位,仅触发不插入新行逻辑
    ';

    $stmt = $conn->prepare($sql);
    // 若race_id是字符串类型,把'i'改成's'
    $stmt->bind_param('i', $race_id);

    if ($stmt->execute()) {
        $message = '<p align="center">记录处理成功<br>';
    } else {
        $message = "Error: " . $stmt->error . '<br>';
    }
    echo $message;
    $stmt->close();
}
?>

补充说明

如果表中有其他需要更新的字段,把ON DUPLICATE KEY UPDATE后的内容替换为实际需要更新的字段,比如:

ON DUPLICATE KEY UPDATE
    race_name = VALUES(race_name),
    race_time = VALUES(race_time)

内容的提问来源于stack exchange,提问作者Nikos Kioses

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 22:30:50