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

MySQL LAST_INSERT_ID() 函數行為深度解析

     編輯:MySQL 資料庫相關知識

核心結論先行

LAST_INSERT_ID() 返回最近一條 INSERT 語句中,AUTO_INCREMENT 列自動生成的第一個值。

關鍵限制:

  1. 僅跟踪 自動生成 的值(显式指定值不計入)
  2. 多行 INSERT 僅返回 第一行 的自動生成值
  3. 會話級隔離,不受並發影響

實驗驗證

CREATE TABLE t_id (id INT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;

-- 1. 單行隱式插入
INSERT INTO t_id VALUES ();
SELECT LAST_INSERT_ID(); -- 1 ✅

-- 2. 單行隱式插入
INSERT INTO t_id VALUES ();
SELECT LAST_INSERT_ID(); -- 2 ✅

-- 3. 多行隱式插入(3 行)
INSERT INTO t_id VALUES (), (), ();
SELECT LAST_INSERT_ID(); -- 3 ❌ 預期 5,實際返回第一行生成值 3

-- 4. 再次多行插入
INSERT INTO t_id VALUES (), (), ();
SELECT LAST_INSERT_ID(); -- 6 ✅ 第一行生成值 6

-- 5. 顯式指定值
INSERT INTO t_id VALUES (10);
SELECT LAST_INSERT_ID(); -- 6 ❌ 仍返回 6,因為未觸發自動生成

官方文檔原文對照

With no argument, LAST_INSERT_ID() returns a 64-bit value representing the first automatically generated value successfully inserted for an AUTO_INCREMENT column as a result of the most recently executed INSERT statement.

If you insert multiple rows using a single INSERT statement, LAST_INSERT_ID() returns the value generated for the first inserted row only.

常見誤區與避坑

誤區真相正確做法
以為返回最後一行 ID返回第一行自動生成 ID單行插入或應用層計算
顯式指定 ID 後以為會更新不更新,仍保持上次自動生成值避免業務依賴此場景
以為是全局/跨會話共享會話級隔離,線程安全放心在高併發使用
以為 UPDATE 會觸發僅 INSERT 觸發更新不影響

進階用法:帶參數形式

-- 手動設置會話級 LAST_INSERT_ID
INSERT INTO t_id VALUES (NULL);
SET @my_id = LAST_INSERT_ID();

-- 後續語句可引用
INSERT INTO t_child (parent_id, data) VALUES (@my_id, 'child data');
-- 或
SELECT LAST_INSERT_ID(@my_id); -- 設置並返回 @my_id

應用層最佳實踐

  1. 單條 INSERT 獲取 ID: 標準場景,直接調用
  2. 批量插入需獲取所有 ID:
    • 方案 A:分批單條插入(性能差)
    • 方案 B:預先獲取 ID 段(SELECT AUTO_INCREMENT FROM information_schema.TABLES)
    • 方案 C:應用層生成 UUID/雪花算法 ID,不依賴自增
  3. 事務中回滾: 回滾不影響 LAST_INSERT_ID,下次插入仍從內存計數器續增(可能產生間隙)

總結

LAST_INSERT_ID() 設計初衷是單條 INSERT 後獲取自增 ID,完美支持「主表插入 → 獲取 ID → 子表插入」模式。多行插入、顯式指定值等場景超出設計範圍,切勿強行依賴。記住口訣:最近一條 INSERT,第一個自動生成值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved