mysql update last_insert_id_对mysql中last_insert_id()的新理解

先来看看官方的说明

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)

参考:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值