文档章节

对mysql中last_insert_id()的新理解

安小乐
 安小乐
发布于 2017/07/13 10:37
字数 1131
阅读 34
收藏 0

先来看看官方的说明

The ID that was generated is maintained in the server on a per-connection basis. 
This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. 
This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. 
This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.

看到了吧!last_insert_id()函数的返回值不是基于整个数据库的插入语句,
而是基于单个连接客户端之间所执行的insert语句最近一条,而且客户端之间是不会影响的,它是连接级别的函数,只对当前用户的连接有效。

=============================================================

以下文章来源于网络(文笔比我好,哈哈)

在MySQL中,使用auto_increment类型的id字段作为表的主键。

通常的做法,是通过“select max(id) from tablename”的做法,但是显然这种做法需要考虑并发的情况,需要在事务中对主表加以“X锁“,待获得max(id)的值以后,再解锁。

这种做法需要的步骤比较多,有些麻烦,而且并发性也不好。有没有更简单的做法呢?答案之一是通过select LAST_INSERT_ID()这个操作。

乍一看,它和select max(id)很象,但实际上它是线程安全的。也就是说它是具体于数据库连接的。下面通过实验说明:

(1)、在连接1中向A表插入一条记录,A表包含一个auto_increment类型的字段。

(2)、在连接2中向A表再插入一条记录。

(3)、结果:在连接1中执行select 得到的结果和连接2中执行select LAST_INSERT_ID()的结果是不同的;而在两个连接中执行select max(id)的结果是相同的。LAST_INSERT_ID()

其实在MSSQL中SCOPE_IDENTITY()和IDENT_CURRENT()的区别和这里是类似的。使用SCOPE_IDENTITY()可以获得插入某个IDENTITY字段的当前会话的值,而使用IDENT_CURRENT()会获得在某个IDENTITY字段上插入的最大值,而不区分不同 的会话。

注:使用select last_insert_id()时要注意,当一次插入多条记录时,只是获得第一次插入的id值,务必注意!

LAST_INSERT_ID 是与table无关的,如果向表a插入数据后,再向表b插入数据,LAST_INSERT_ID会改变。(这句话说明,LAST_INSERT_ID 还是有可能出现线程问题。)

一般情况下获取刚插入的数据的id,使用select max(id) from table 是可以的。

但在多线程情况下,就不行了。在多用户交替插入数据的情况下max(id)显然不能用。

这就该使用LAST_INSERT_ID了,因为LAST_INSERT_ID是基于Connection的,只要每个线程都使用独立的Connection对象,LAST_INSERT_ID函数将返回该Connection对AUTO_INCREMENT列最新的insert or update操作生成的第一个record的ID。这个值不能被其它客户端(Connection)影响,保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁。

 

 

 

用PHP调用mysql,内置的LAST_INSERT_ID()这个函数可能没有什么人用,用的最多的还是mysql_insert_id()其实,这两个是有区别的,LAST_INSERT_ID()能返回bigint值的id。而mysql_insert_id返回的是int。如果你的id是unsignedint,或者bigint的。那么,可能是返回的是错误的。而要用LAST_INSERT_ID()代替。

还有些朋友,返回的都是0,不知道怎么回事,其实LAST_INSERT_ID()返回的是AUTO_INCREMENT的ID。 如果表结构中,没有设置AUTO_INCREMENT那么也无法返回。

还有些人,还是返回为0.那么你就要检查一下,如果用了insert delay的功能,则不会即时的返回id值的。

很多人喜欢用select max(id)...来替换这个last_insert_id,实际上,select max(id)是非线程安全的,很有可能,其他线程插入了新的数据,你就查不到你上次插入的ID了。而last_insert_id是和一个mysql connect相对应的,也就是和你的当前线程相对应的,不会受其他线程的干扰。如果你的数据库发生了一些奇怪的错误,比如,本来是要更新A数据的信息的,结果B数据被更新了,而且是有时候正确,有时候不正确,人多的时候会非常的不正确。就要看看是不是用了select max(id)

 

参考:

对mysql中last_insert_id()的新理解

MYSQL 小技巧 -- LAST_INSERT_ID

本文转载自:http://sucre.blog.51cto.com/1084905/723808

安小乐
粉丝 18
博文 179
码字总数 77673
作品 0
朝阳
后端工程师
私信 提问
分库主键设计-Mysql

常见的两种方案,遍布网络: 第一种: replace方案,mysql解释:REPLACE的运行与INSERT很相像。只有一点除外,如果表中的一个旧记录与一个用于PRIMARY KEY或一个UNIQUE索引的新记录具有相同的...

伊人梦醉
2016/06/20
29
0
MySQL Replace语句

在本教程中,您将学习如何使用 MySQL的语句来插入或更新数据库表中的数据。 MySQL REPLACE语句介绍 MySQL的REPLACE语句是一个MySQL扩展于SQL标准的语句。 MySQL REPLACE语句的工作原理如下:...

易百教程
2016/09/20
27
0
mysql LAST_INSERT_ID详解

LASTINSERTID() LASTINSERTID(expr) 自动返回最后一个INSERT或 UPDATE 问询为 AUTO_INCREMENT列设置的第一个 发生的值。 mysql> SELECT LASTINSERTID(); -> 195 产生的ID 每次连接后保存在服...

刘德生
2013/09/11
289
0
pt-online-schema-change 实现在线DDL

参考文章:http://seanlook.com/2016/05/27/mysql-pt-online-schema-change/ 上面的文章写的很详细,在这篇文章中,想要再补充一些自己的理解。 一、在原表创建的三个触发器,在copy数据时,...

star_glm
2018/03/08
46
0
last_insert_id()获取mysql最后一条记录ID

lastinsertid()自动返回最后一个INSERT或 UPDATE 查询中 AUTO_INCREMENT列设置的第一个表发生的值。 MySQL的LASTINSERTID的注意事项: 第一、查询和插入所使用的Connection对象必须是同一个才...

技术小胖子
2017/11/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
今天
2.4K
15
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
今天
41
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
40
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
61
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
21
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部