首页/数据/SQL 速查/LAST_INSERT_ID 与自增主键回填
变更与事务52 条

LAST_INSERT_ID 与自增主键回填

取刚插入行的自增主键:MySQL 的 LAST_INSERT_ID() 是连接级值,不随其它连接变化;PostgreSQL 用 RETURNING 或 currval。

SQL 速查数据更新于 2026-10-13

LAST_INSERT_ID 是什么

MySQL 的 LAST_INSERT_ID() 返回当前连接最近一次插入所生成的自增主键。它是连接级的值,不随其它连接的变化而变;多行插入时返回第一行的值。PostgreSQL 没有这个函数,用 INSERT ... RETURNING 取回主键才是标准做法。

基本信息

MySQLLAST_INSERT_ID(),按连接隔离,不会读到别的事务的结果
多行插入返回第一行生成的自增值,不是最后一个
PostgreSQL用 INSERT ... RETURNING id 一步取回
PG 序列取值currval(pg_get_serial_sequence('表','列')),需同会话先取过一次
禁止写法不要用 SELECT MAX(id),并发下必然取错
连接池取值必须与插入在同一条连接上完成

MySQL 取值

MySQL 取值
INSERT INTO orders (user_id, amount) VALUES (10, 99.00);
SELECT LAST_INSERT_ID();   -- 本连接本次插入生成的主键

INSERT INTO orders (user_id, amount)
VALUES (10, 1.00), (10, 2.00);   -- 多行插入
SELECT LAST_INSERT_ID();         -- 返回第一行生成的那个值
-- 需要拿到全部主键时,逐行插入或用其它方式回查

PostgreSQL 取值

PostgreSQL 取值
INSERT INTO orders (user_id, amount) VALUES (10, 99.00)
RETURNING id, created_at;   -- 推荐:插入与取值在一条语句里完成

-- 需要知道序列名时的写法
SELECT currval(pg_get_serial_sequence('orders', 'id'));
-- currval 要求本会话已经取过该序列,否则直接报错

取值方式对比

方式MySQL 8PostgreSQL
插入即取回没有 RETURNING,需要再查一次INSERT ... RETURNING 一步完成
取自增主键LAST_INSERT_ID()RETURNING id 或 currval
批量插入返回首行生成的值RETURNING 逐行返回
并发安全连接级取值,安全RETURNING 与 currval 安全
错误做法SELECT MAX(id)SELECT MAX(id)

典型使用场景

  • 下单后立刻拿订单号写入明细表
  • 批量导入后回填主表与从表的关联关系
  • 写主表后把主键写进日志或消息,供下游消费
  • 把自增主键作为幂等键回传给调用方
  • 数据修复脚本插入补录记录并记录新主键
  • 排查取值异常:确认插入与取值是否走了同一条连接
这个值是连接级的、与表无关:同一个连接里先插 A 表再插 B 表,返回的是最近一次针对自增列的插入值。连接池场景务必确认两步走的是同一条连接。
SELECT MAX(id) 在并发写入下几乎必然出错:读到的是别人插入的更大值,还会给主键查询增加额外扫描。自增主键必须用连接级函数或 RETURNING 取回。

易错点

  • 连接池里用了两条连接:插入与取值落在不同连接上,LAST_INSERT_ID() 返回 0 或别人的值
  • 用 SELECT MAX(id) 取刚插入的主键:并发下必然取错,改用 LAST_INSERT_ID 或 RETURNING
  • 以为多行插入返回最后一行的值:MySQL 返回的是首行生成值,需要全部主键就逐行插入
  • PG 里用 currval 但本会话没取过序列:直接报错,改用 RETURNING 更省事也更清晰

数据来源与参考

  • MySQL 8.0 Reference Manual · LAST_INSERT_ID
  • PostgreSQL Documentation · Sequence Functions
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌