在使用MySQL时,若表中含自增字段(auto_increment类型),则向表中insert一条记录后,可以调用last_insert_id()来获得最近insert的那行记录的自增字段值
$mdb->lastInsertId();
但事实上,使用last_insert_id()时有很多注意事项,否则很容易踩到坑。
若在同一条insert语句中插入多行(如"insert into tbl_name (col_a, col_b) values ('aa', 'bb'), ('aaa', 'bbb')"这类SQL语句),则last_insert_id()返回的自增字段的"当前值"只在旧值的基础上加1,这与实际情况不符(表中的实际情况是自增字段值在旧值基础上加N)!
3. 假设用形如"INSERT ... ON DUPLICATE KEY UPDATE"的SQL语句更新表,此时,若该语句的实际作用是insert操作时,调用last_insert_id()会返回本次insert后自增字段的当前值;而若该语句的实际作用是update操作时,调用last_insert_id()返回的是自增字段的旧值,而非当前更新行的自增字段值,所以这个值无意义(因为调用last_insert_id()是想获取sql影响到的行的自增字段值进而做其它逻辑业务的,如果得到的值并非sql操作影响到的行对应的自增值,则这个值对业务来说无意义),按照MySQL手册的说明,若业务开发者想得到实际update操作影响到的行的自增值,可以用形如"INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;"的SQL语句来获取。
关于带参数的last_insert_id()函数的使用说明,可以参考本文第8条的说明。
若在SQL中显式指定自增字段的值,如假设某张表由两列(id, name)构成,其中id为自增类型,假设当前表中id值为2,那么,执行"insert into test_tbl (id, name) values (11, 'test3');"后,再执行"select last_insert_id()",可以发现,得到的结果依旧是2。也即,只有自增字段由mysql来分配时,last_insert_id()才可能得到正确的值;SQL中显式更新自增字段值时,last_insert_id()返回的值不可用!
如果sql语句执行出错,则调用last_insert_id()的值未定义。例如,若事务因执行出错回滚,则last_insert_id()的值不会恢复到事务执行前的那个值。
last_insert_id()的值是由MySQL server来维护的,而且是为每条连接维护独立的值,也即,某条连接调用last_insert_id()获取到的值是这条连接最近一次insert操作执行后的自增值,该值不会被其它连接的sql语句所影响。这个行为保证了不同的连接能正确地获取到它最近一次insert sql执行所插入的行的自增值,也就是说,last_insert_id()的值不需要通过加锁或事务机制来保证其在多连接场景下的正确性。
如果通过"insert ignore"语句尝试插入新纪录,假设由于unique key冲突导致插入不成功,则auto_increment计数器不会变化,根据MySQL手册的说明,此时调用last_insert_id()会返回0表示没有新行被插入。但我在MySQL 5.1.73版本上测试的结果显示,last_insert_id()只是维持旧值而已,并不会返回0。
8. last_insert_id(expr)的行为
若调用last_insert_id()时传入了参数,则它会将参数值返回给调用者,并记住这个值,下次调用不带参数的last_insert_id()时,仍会返回这个值。可以利用这个特性实现一个多用户安全的全局计数器,示例如下:
1) 先创建一张表
mysql> CREATE TABLE sequence (id INT NOT NULL);
mysql> INSERT INTO sequence VALUES (0);
2) 每条连接执行下面的SQL语句来获取为其自动分配的全局唯一ID
mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql> SELECT LAST_INSERT_ID();
每次都会id+1
当然,上面给出的全局ID分配器只是一种思路,在实际工程实现中,频繁的update操作可能会造成系统瓶颈,可以参考PERCONA MYSQL PERFORMANCE BLOG这篇文章的优化思路(比如MySQL前面用cache抗read压力,通过delay update来减缓update压力)。
参考:

mysql LAST_INSERT_ID 使用与注意事项的更多相关文章

  1. mysql 创建表时注意事项

    mysql  创建表时注意事项 mysql 想必大家都不会陌生吧  是我学习中第一个接触的的数据库 已学习就很快上手的   这是一个关系型数据库  不懂什么是关系型数据库 啊哈哈哈  现在知道啦  因 ...

  2. MySQL数据库使用时注意事项

    MySQL数据库使用时注意事项 建表的角度上 1.合理安排表关系 2.尽量把固定长度的字段放在前面 3.尽量使用char 代替varchar 4.分表:水平分和垂直分 在使用sql语句的时候 1.尽量 ...

  3. mysql索引设计的注意事项

    mysql索引设计的注意事项 目录 一.索引的重要性 二.执行计划上的重要关注点 (1).全表扫描,检索行数 (2).key,using index(覆盖索引) (3).通过key_len确定究竟使用 ...

  4. mysql索引设计的注意事项(大量示例,收藏再看)

    mysql索引设计的注意事项(大量示例,收藏再看) 目录 一.索引的重要性 二.执行计划上的重要关注点 (1).全表扫描,检索行数 (2).key,using index(覆盖索引) (3).通过ke ...

  5. MySQL建立索引的注意事项

    对于大数据量的表格,尤其是百万行以上的数据表,一定要对其建立索引,否则查询速度极慢.(参考后面的测试结果)建立索引时需注意: MySQL的索引有两种:单列索引(即在某一列上建索引).多列组合索引(即在 ...

  6. mysql索引分类及注意事项

    MYSQL索引主要分为四类:主键索引,普通索引(聚合,非聚合),唯一索引,全文索引 全文索引,主要是针对对文件,文本的检索, 比如文章, 全文索引针对MyISAM有用. 索引的原理:利用二叉树(哈希表 ...

  7. 使用mysql索引技巧及注意事项

    一.索引的作用 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 在数据 ...

  8. mysql使用索引的注意事项

    使用索引的注意事项 使用索引时,有以下一些技巧和注意事项: 1.索引不会包含有NULL值的列 只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索 ...

  9. mysql LAST_INSERT_ID详解

    http://blog.sina.com.cn/s/blog_5b5460eb0100nwvo.html LAST_INSERT_ID() LAST_INSERT_ID(expr) 自动返回最后一个I ...

随机推荐

  1. windows配置nginx实现负载均衡集群

    windows配置nginx实现负载均衡集群2014-08-20 09:44:40   来源:www.abcde.cn   评论:0 点击:617 网上大部分关于nginx负载均衡集群的教程都是lin ...

  2. Maven 安装

    简单记录maven的安装步骤: 在安装maven之前,先确保已经安装JDK1.6及以上版本,并且配置好环境变量. 下载maven3,最新版本是Maven3.2.3 ,下载地址:http://maven ...

  3. MVP设计模式的实现

    MVP:界面与业务逻辑分离在Winform中的应用 MVP,Model-View-Presenter的缩写. 在MSDN上,下载了一个示例,http://www.microsoft.com/china ...

  4. 【mongo】Can't take a write lock while out of disk space错误

    今天遇到了这个错误,各种无法操作.找了很久的方案,都没用.最终发现,原来是我虚拟机硬盘满了......清除了些没用的东西,就恢复了.

  5. 20145213《Java程序设计》实验二Java面向对象程序设计实验报告

    20145213<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装,继承,多态 初步掌握UML建模 熟悉S.O. ...

  6. 让ar执行queryall和queryrow方法返回数组

    让ar执行queryall和queryrow方法返回数组 <?phpnamespace common\components;use \CActiveRecord;use \Yii;use \CD ...

  7. webApp路由控制-vue-router2.0

    安装 直接下载 / CDN https://unpkg.com/vue-router 中文api: http://router.vuejs.org/zh-cn/index.html

  8. 字符匹配算法之KMP

    KMP算法的精华在于从前往后,逐步循环地向前滑动搜索词,来最大限度地减少重复匹配次数,以达到提高效率的目的. 移动位数=已匹配字符数-最后一个匹配字符所对应搜索词的位置[从1开始]. 更加详细且具体的 ...

  9. 手工加载DLL

    1.为了能找到dll的函数地址,生成dll时需要将其中的函数声明为C函数(extern "C"): #ifndef __MYDLL_H#define __MYDLL_H #ifde ...

  10. poj1308(简单并查集)

    题目链接:http://poj.org/problem?id=1308 题意:x, y 表示x 与 y连接,给出一波这样的数据,问这组数据能否构成树,即不能形成回路,不能有多个根节点:要注意可以是空树 ...