首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 主從表插入:如何安全高效獲取自增 ID?LAST_INSERT_ID() 實戰解析

     編輯:MySQL 資料庫相關知識

在採用 AUTO_INCREMENT 主鍵的主從表設計中,常見流程是:先寫入主表,取得自動生成的 ID,再以此 ID 寫入從表。關鍵難點在於併發環境下如何精準獲取「當前連線」剛插入的 ID。

傳統做法與缺陷

早期常用 SELECT MAX(id) FROM table,但此法在高併發下極不靠譜:

  • 需在事務中對主表加排他鎖(X 鎖),序列化寫入,效能大打折扣。
  • 若未加鎖,極易讀取到其他執行緒插入的 ID,導致資料關聯錯誤。

正解:LAST_INSERT_ID() — 連線級別的線程安全

MySQL 提供 LAST_INSERT_ID() 函數,其返回值嚴格綁定當前資料庫連線(Session),互不干擾,無需加鎖,效能極佳。

實驗驗證併發隔離性

  1. 連線 1 向表 A 插入一筆資料(含 auto_increment 欄位)。
  2. 連線 2 向表 A 再插入一筆資料。
  3. 分別在兩連線執行 SELECT LAST_INSERT_ID(),結果各自返回自己插入的 ID,互不影響。
  4. 若改用 SELECT MAX(id),兩連線則會得到相同的最大值,無法區分。

此機制類似 SQL Server 的 SCOPE_IDENTITY()(當前作用域/連線),而非 IDENT_CURRENT()(全表最大值)。

重要陷阱:批次插入僅返回第一筆 ID

INSERT INTO tb (c1, c2) VALUES (v1, v2), (v3, v4), (v5, v6);
SELECT LAST_INSERT_ID(); -- 僅返回第一筆 (v1,v2) 的 ID

若批次寫入後需獲取所有 ID,建議:

  • 拆分為多條單筆 INSERT,逐筆獲取。
  • 或在應用層預估 ID 範圍(僅在無併發插入時可行)。
  • 或使用 INSERT ... RETURNING(MySQL 8.0.27+ 支援)。

最佳實踐建議

  1. 永遠使用 LAST_INSERT_ID() 獲取剛插入的自增 ID,拒絕 MAX(id)。
  2. 應用程式保持長連線或連線池,確保同一邏輯操作複用同一連線。
  3. 批次寫入場景,評估改用單筆迴圈或升級 MySQL 版本使用 RETURNING 子句。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved