刘亦菲是我老婆 發表於 2026-1-10 09:30:43

Node.js使用mysql2 库批量更新(Bulk Update)多条数据的方案

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">方法一:使用CASE WHEN语句(推荐:单条 SQL 完成)</a></li><li><a href="#_label1">方法二:使用INSERT ... ON DUPLICATE KEY UPDATE(性能最高)</a></li><li><a href="#_label2">方法三:使用事务 + 循环更新 (最安全/逻辑最简单)</a></li><li><a href="#_label3">总结与对比</a></li><li><a href="#_label4">💡 进阶技巧:</a></li></ul></div><p>在 Node.js 中使用 <code>mysql2</code> 库批量更新(Bulk Update)多条数据,主要有三种主流方案。由于 MySQL 本身没有像 <code>INSERT</code> 那样简单的 <code>UPDATE ... VALUES (...)</code> 语法,我们需要根据场景选择最合适的方法。</p>
<p class="maodian"><a name="_label0"></a></p><h2>方法一:使用CASE WHEN语句(推荐:单条 SQL 完成)</h2>
<p>这是最通用的批量更新方法。通过 SQL 的 <code>CASE</code> 语法,可以根据主键 ID 一次性更新多条记录的不同字段。</p>
<p><strong>适用场景:</strong> 更新条数在几十到几百条左右,性能较好。</p>
<div class="jb51code"><pre class="brush:js;">const mysql = require('mysql2/promise');
async function batchUpdate(data) {
const connection = await mysql.createConnection({/* config */});
// 假设 data 结构为: [{id: 1, name: 'A', age: 20}, {id: 2, name: 'B', age: 25}]
let ids = [];
let nameCases = '';
let ageCases = '';
let params = [];
data.forEach(item =&gt; {
    ids.push(item.id);
    nameCases += `WHEN ? THEN ? `;
    params.push(item.id, item.name);
    ageCases += `WHEN ? THEN ? `;
    params.push(item.id, item.age);
});
// 最后的 params 顺序需要和 SQL 中的问号顺序一致
// 这里为了简化演示直接拼接,实际建议通过数组 push 控制顺序
const sql = `
    UPDATE users
    SET
      name = CASE id ${nameCases} END,
      age = CASE id ${ageCases} END
    WHERE id IN (${ids.map(() =&gt; '?').join(',')})
`;
// 合并参数:
const finalParams = [...params, ...ids];
await connection.execute(sql, finalParams);
}</pre></div>
<p class="maodian"><a name="_label1"></a></p><h2>方法二:使用INSERT ... ON DUPLICATE KEY UPDATE(性能最高)</h2>
<p>如果你的表有<strong>主键(Primary Key)<strong>或</strong>唯一索引(Unique Index)</strong>,这是最高效的方法。它的原理是:尝试插入数据,如果主键冲突,则执行更新。</p>
<p><strong>注意:</strong> 如果数据不存在,它会变成<strong>插入</strong>。如果你只想更新不想插入,需要确保传入的 ID 在数据库中已存在。</p>
<div class="jb51code"><pre class="brush:js;">const mysql = require('mysql2/promise');
async function batchUpdateUpsert(data) {
const connection = await mysql.createConnection({/* config */});
// 将数据转为二维数组: [, ]
const values = data.map(item =&gt; );
const sql = `
    INSERT INTO users (id, name, age)
    VALUES ?
    ON DUPLICATE KEY UPDATE
      name = VALUES(name),
      age = VALUES(age)
`;
// mysql2 的 query 方法支持传入二维数组来替换 VALUES ?
await connection.query(sql, );
}</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>方法三:使用事务 + 循环更新 (最安全/逻辑最简单)</h2>
<p>如果你不熟悉复杂的 SQL 拼接,或者需要对每一条更新进行复杂的逻辑判断,可以使用事务(Transaction)包裹多条 <code>UPDATE</code> 语句。</p>
<p><strong>适用场景:</strong> 数据量不大,或者必须保证每条更新的原子性。</p>
<div class="jb51code"><pre class="brush:js;">const mysql = require('mysql2/promise');
async function batchUpdateTransaction(data) {
const connection = await mysql.createConnection({/* config */});
try {
    await connection.beginTransaction();
    for (const item of data) {
      await connection.execute(
      'UPDATE users SET name = ?, age = ? WHERE id = ?',
      
      );
    }
    await connection.commit();
} catch (error) {
    await connection.rollback();
    throw error;
}
}</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>总结与对比</h2>
<table><thead><tr><th>方法</th><th>优点</th><th>缺点</th><th>建议</th></tr></thead><tbody><tr><td><strong>CASE WHEN</strong></td><td>标准 SQL,不依赖唯一键冲突,单次 IO</td><td>拼接 SQL 逻辑复杂,数据量过大时 SQL 字符串超长</td><td><strong>中等规模更新首选</strong></td></tr><tr><td><strong>ON DUPLICATE KEY</strong></td><td><strong>速度最快</strong>,代码最简洁</td><td>必须有主键/唯一索引,会意外插入不存在的数据</td><td><strong>超大规模更新首选</strong></td></tr><tr><td><strong>事务循环</strong></td><td>逻辑最清晰,支持复杂判断</td><td>数据库往返 IO 次数多,性能相对较低</td><td><strong>小批量或逻辑复杂时使用</strong></td></tr></tbody></table>
<p class="maodian"><a name="_label4"></a></p><h2>💡 进阶技巧:</h2>
<p>如果批量更新的数据量达到 <strong>万级</strong> 以上:</p>
<ol><li><strong>分批执行:</strong> 不要一次性发 10 万条,建议每 500-1000 条作为一组进行批量操作。</li><li><strong>临时表法:</strong> 先将数据 <code>LOAD DATA</code> 或批量插入到一个临时表,然后使用 <code>UPDATE users JOIN temp_users ...</code> 的语法进行关联更新。这是处理百万级数据最快的方式。</li></ol>
頁: [1]
查看完整版本: Node.js使用mysql2 库批量更新(Bulk Update)多条数据的方案