Node.js使用mysql2 庫批量更新(Bulk Update)多條數(shù)據(jù)的方案
在 Node.js 中使用 mysql2 庫批量更新(Bulk Update)多條數(shù)據(jù),主要有三種主流方案。由于 MySQL 本身沒有像 INSERT 那樣簡單的 UPDATE ... VALUES (...) 語法,我們需要根據(jù)場景選擇最合適的方法。
方法一:使用CASE WHEN語句(推薦:單條 SQL 完成)
這是最通用的批量更新方法。通過 SQL 的 CASE 語法,可以根據(jù)主鍵 ID 一次性更新多條記錄的不同字段。
適用場景: 更新條數(shù)在幾十到幾百條左右,性能較好。
const mysql = require('mysql2/promise');
async function batchUpdate(data) {
const connection = await mysql.createConnection({/* config */});
// 假設(shè) data 結(jié)構(gòu)為: [{id: 1, name: 'A', age: 20}, {id: 2, name: 'B', age: 25}]
let ids = [];
let nameCases = '';
let ageCases = '';
let params = [];
data.forEach(item => {
ids.push(item.id);
nameCases += `WHEN ? THEN ? `;
params.push(item.id, item.name);
ageCases += `WHEN ? THEN ? `;
params.push(item.id, item.age);
});
// 最后的 params 順序需要和 SQL 中的問號(hào)順序一致
// 這里為了簡化演示直接拼接,實(shí)際建議通過數(shù)組 push 控制順序
const sql = `
UPDATE users
SET
name = CASE id ${nameCases} END,
age = CASE id ${ageCases} END
WHERE id IN (${ids.map(() => '?').join(',')})
`;
// 合并參數(shù):[name的id和值..., age的id和值..., WHERE用的id列表]
const finalParams = [...params, ...ids];
await connection.execute(sql, finalParams);
}方法二:使用INSERT ... ON DUPLICATE KEY UPDATE(性能最高)
如果你的表有主鍵(Primary Key)或唯一索引(Unique Index),這是最高效的方法。它的原理是:嘗試插入數(shù)據(jù),如果主鍵沖突,則執(zhí)行更新。
注意: 如果數(shù)據(jù)不存在,它會(huì)變成插入。如果你只想更新不想插入,需要確保傳入的 ID 在數(shù)據(jù)庫中已存在。
const mysql = require('mysql2/promise');
async function batchUpdateUpsert(data) {
const connection = await mysql.createConnection({/* config */});
// 將數(shù)據(jù)轉(zhuǎn)為二維數(shù)組: [[1, 'A', 20], [2, 'B', 25]]
const values = data.map(item => [item.id, item.name, item.age]);
const sql = `
INSERT INTO users (id, name, age)
VALUES ?
ON DUPLICATE KEY UPDATE
name = VALUES(name),
age = VALUES(age)
`;
// mysql2 的 query 方法支持傳入二維數(shù)組來替換 VALUES ?
await connection.query(sql, [values]);
}方法三:使用事務(wù) + 循環(huán)更新 (最安全/邏輯最簡單)
如果你不熟悉復(fù)雜的 SQL 拼接,或者需要對(duì)每一條更新進(jìn)行復(fù)雜的邏輯判斷,可以使用事務(wù)(Transaction)包裹多條 UPDATE 語句。
適用場景: 數(shù)據(jù)量不大,或者必須保證每條更新的原子性。
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 = ?',
[item.name, item.age, item.id]
);
}
await connection.commit();
} catch (error) {
await connection.rollback();
throw error;
}
}總結(jié)與對(duì)比
| 方法 | 優(yōu)點(diǎn) | 缺點(diǎn) | 建議 |
|---|---|---|---|
| CASE WHEN | 標(biāo)準(zhǔn) SQL,不依賴唯一鍵沖突,單次 IO | 拼接 SQL 邏輯復(fù)雜,數(shù)據(jù)量過大時(shí) SQL 字符串超長 | 中等規(guī)模更新首選 |
| ON DUPLICATE KEY | 速度最快,代碼最簡潔 | 必須有主鍵/唯一索引,會(huì)意外插入不存在的數(shù)據(jù) | 超大規(guī)模更新首選 |
| 事務(wù)循環(huán) | 邏輯最清晰,支持復(fù)雜判斷 | 數(shù)據(jù)庫往返 IO 次數(shù)多,性能相對(duì)較低 | 小批量或邏輯復(fù)雜時(shí)使用 |
?? 進(jìn)階技巧:
如果批量更新的數(shù)據(jù)量達(dá)到 萬級(jí) 以上:
- 分批執(zhí)行: 不要一次性發(fā) 10 萬條,建議每 500-1000 條作為一組進(jìn)行批量操作。
- 臨時(shí)表法: 先將數(shù)據(jù)
LOAD DATA或批量插入到一個(gè)臨時(shí)表,然后使用UPDATE users JOIN temp_users ...的語法進(jìn)行關(guān)聯(lián)更新。這是處理百萬級(jí)數(shù)據(jù)最快的方式。
到此這篇關(guān)于Node.js使用mysql2 庫批量更新(Bulk Update)多條數(shù)據(jù)的方案的文章就介紹到這了,更多相關(guān)node.js批量更新數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Nest.js參數(shù)校驗(yàn)和自定義返回?cái)?shù)據(jù)格式詳解
這篇文章主要給大家介紹了關(guān)于Nest.js參數(shù)校驗(yàn)和自定義返回?cái)?shù)據(jù)格式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
node+express+ejs使用模版引擎做的一個(gè)示例demo
本篇文章主要介紹了node+express+ejs使用模版引擎做的一個(gè)示例demo,具有一定參考價(jià)值,有興趣的小伙伴可以了解一下2017-09-09
Node.js開發(fā)之訪問Redis數(shù)據(jù)庫教程
這篇文章主要介紹了Node.js開發(fā)之訪問Redis數(shù)據(jù)庫教程,本文講解了安裝Redis的Node.js驅(qū)動(dòng)、編寫測試程序以及npm遠(yuǎn)程服務(wù)器連接十分緩慢的解決方法,需要的朋友可以參考下2015-01-01
Node.js+ES6+dropload.js實(shí)現(xiàn)移動(dòng)端下拉加載實(shí)例
這個(gè)demo服務(wù)由Node搭建服務(wù)、下拉加載使用插件dropload,數(shù)據(jù)渲染應(yīng)用了ES6中的模板字符串。有興趣的小伙伴可以自己嘗試下2017-06-06
在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線推送的方法
這篇文章主要介紹了在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線推送的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01
node.js實(shí)現(xiàn)端口轉(zhuǎn)發(fā)
這篇文章主要為大家詳細(xì)介紹了node.js實(shí)現(xiàn)端口轉(zhuǎn)發(fā)的關(guān)鍵代碼,感興趣的小伙伴們可以參考一下2016-04-04

