首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL LAST_INSERT_ID() 函數深度解析:獲取自增 ID 的正確姿勢

     編輯:MySQL 綜合教學

MySQL LAST_INSERT_ID() 函數深度解析:獲取自增 ID 的正確姿勢

函數作用

返回當前連接最近一次 INSERT 或 UPDATE 語句中,第一條記錄自動生成的 AUTO_INCREMENT 值。

基本用法

-- 插入數據
INSERT INTO test_table (col1, col2) VALUES ('val1', 'val2');

-- 獲取自增 ID
SELECT LAST_INSERT_ID();
-- 結果:195(假設該行自增 ID 為 195)

PHP 完整示例

$query = "INSERT INTO `testtable` (`col1`, `col2`) VALUES ('testvalue', 'test')";
mysql_query($query);

$query = "SELECT LAST_INSERT_ID()";
$result = mysql_query($query);
$row = mysql_fetch_row($result);
echo $row[0];  // 輸出剛插入記錄的自增 ID

核心特性(必須理解)

特性說明影響
連接隔離每個連接維護獨立的 LAST_INSERT_ID高併發下絕不會取到其他連接的 ID,極其安全
同一連接查詢與插入必須用同一連接對象連接池場景需確保同一連接,否則結果不可預期
表無關插入表 A 後插入表 B,返回表 B 的 ID跨表操作時注意順序
多行插入僅返回第一行的自增值批量插入 100 行,只返回第 1 行 ID
事務回滾回滾不影響已生成的 ID(ID 已消耗)自增 ID 可能出現間隙
UPDATE 觸發若 UPDATE 導致 AUTO_INCREMENT 列變化,也會更新罕見場景

為什麼不用 SELECT MAX(id)?

-- 錯誤做法(高併發下極不安全)
SELECT MAX(id) FROM table;

高併發時,連接 A 插入後未查 MAX,連接 B 插入並查 MAX,連接 A 查到的可能是 B 的 ID。

批量插入時的行為

INSERT INTO t VALUES (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
SELECT LAST_INSERT_ID();  -- 返回第一行的 ID(如 2),而非最後一行(4)

設計目的:便於主從複製時,從庫重放相同語句產生相同 ID 序列。

LAST_INSERT_ID(expr) 帶參數形式

SELECT LAST_INSERT_ID(100);  -- 返回 100,並將連接內部計數器設為 100
SELECT LAST_INSERT_ID();     -- 後續調用返回 100

少用,特殊業務需手動設置下一自增值時使用。

各語言/驅動獲取方式

語言/驅動獲取方法
JDBC (MySQL Connector/J)Statement.getGeneratedKeys() 或 Connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
Python (mysqlclient/PyMySQL)cursor.lastrowid
Go (go-sql-driver/mysql)result.LastInsertId()
Node.js (mysql2)result.insertId
PHP (mysqli)$mysqli->insert_id
PHP (PDO)$pdo->lastInsertId()

最佳實踐

  1. 使用驅動原生 getGeneratedKeys/lastrowid/insert_id,避免額外查詢
  2. 批量插入需獲取所有 ID 時,考慮分批插入或預先生成 ID(如 UUID、Snowflake)
  3. 分庫分表場景,自增 ID 不再全局唯一,建議改用分布式 ID 生成器
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved