mysql中的last_insert_id()
来源:互联网 发布:矩阵乘法分配律 编辑:程序博客网 时间:2024/05/17 01:47
刚才查了下last_insert_id()相关资料,找到几篇不错的文章,保存下来,免得下次忘了又去找。
#################################
MySQL数据表结构中,一般情况下,都会定义一个具有‘AUTO_INCREMENT’扩展属性的‘ID’字段,以确保数据表的每一条记录都可以用这个ID唯一确定;
随着数据的不断扩张,为了提高数据库查询性能,降低查询热点,一般都会把一张表按照一定的规则分成多张数据表,即常说的分表;
分表除了表名的索引不同之外,表结构都是一样的,如果各表的‘ID’字段仍采用‘AUTO_INCREMENT’的方式的话,ID就不能唯确定一条记录了。
这时就需要一种处于各个分表之外的机制来生成ID,我们一般采用一张单独的数据表(不妨假设表名为‘ticket_mutex’)来保存这个ID,无论哪个分表有数据增加时,都是先到ticket_mutex表把ID值加1,然后取得ID值。
这个取ID的操作看似很复杂,所幸的是,MySQL提供了LAST_INSERT_ID机制,让我们能一步完成。
1、新建数据表ticket_mutex
CREATE
TABLE
ticket_mutex (
name
varchar
(32)
NOT
NULL
PRIMARY
KEY
COMMENT
'业务名称'
,
value
bigint
(20) UNSIGNED
NOT
NULL
COMMENT
'ID值'
)Engine=InnoDB
DEFAULT
CHARSET=UTF8 COMMENT
'保存分表ID表'
;
字段‘value’即该业务的ID值。
2、初始化业务和其ID值
INSERT
INTO
ticket_mutex(
name
, value)
values
(
'USER'
, 0),(
'POST'
, 0);
+
------+-------+
|
name
| value |
+
------+-------+
| POST | 0 |
|
USER
| 0 |
+
------+-------+
3、获取分表唯一ID
这个时候就要利用MySQL提供的LAST_INSERT_ID()机制了。
在往用户表里新增一条数据时,获取‘用户ID’:
UPDATE
ticket_mutex
SET
value=LAST_INSERT_ID(value+1)
WHERE
name
=
'USER'
;
SELECT
LAST_INSERT_ID();
+
------------------+
| LAST_INSERT_ID() |
+
------------------+
| 1 |
+
------------------+
+
------+-------+
|
name
| value |
+
------+-------+
| POST | 0 |
|
USER
| 1 |
+
------+-------+
UPDATE
ticket_mutex
SET
value=LAST_INSERT_ID(value+1)
WHERE
name
=
'POST'
;
SELECT
LAST_INSERT_ID();
+
------------------+
| LAST_INSERT_ID() |
+
------------------+
| 1 |
+
------------------+
+
------+-------+
|
name
| value |
+
------+-------+
| POST | 1 |
|
USER
| 1 |
+
------+-------+
从上可以看出,通过MySQL的LAST_INSERT_ID机制,我们可以保证在记录总数不增长的情况下,让业务ID在不断的增加,从而保证了分表ID的唯一性。
4、LAST_INSERT_ID说明
从名字可以看出,LAST_INSERT_ID即为最后插入的ID值,根据MySQL的官方手册说明,它有2种使用方法
一是不带参数:LAST_INSERT_ID(),这种方法和AUTO_INCREMENT属性一起使用,当往带有‘AUTO_INCREMENT’属性字段的表中新增记录时,LAST_INSERT_ID()即返回该字段的值,大家可试下(我已经验证过);
二是带有表达式:如上面介绍的LAST_INSERT_ID(value+1),它返回的是表达式的值,即‘value+1’;
##################################
LAST_INSERT_ID() 自动返回最后一个INSERT或 UPDATE 查询中 AUTO_INCREMENT列设置的第一个表发生的值。
MySQL的LAST_INSERT_ID的注意事项:
第一、查询和插入所使用的Connection对象必须是同一个才可以,否则返回值是不可预料的。
mysql> SELECT LAST_INSERT_ID();
-> 100
使用这函数向一个给定Connection对象返回的值是该Connection对象产生对影响AUTO_INCREMENT列的最新语句第一个AUTO_INCREMENT值的。这个值不能被其它Connection对象的影响,即它们产生它们自己的AUTO_INCREMENT值。
第二、LAST_INSERT_ID 是与table无关的,如果向表a插入数据后,再向表b插入数据,LAST_INSERT_ID返回表b中的Id值。
第三、 假如你使用一条INSERT语句插入多个行, LAST_INSERT_ID() 只返回插入的第一行数据时产生的值。其原因是这使依靠其它服务器复制同样的 INSERT语句变得简单。
mysql> INSERT INTO t VALUES
-> (NULL, ‘Mary’), (NULL, ‘Jane’), (NULL, ‘Lisa’);
mysql> SELECT * FROM t;
| id | name |
+—-+——+
| 1 | Bob |
| 2 | Mary |
| 3 | Jane |
| 4 | Lisa |
mysql> SELECT LAST_INSERT_ID(); //这就是我要说明的关键问题。
| LAST_INSERT_ID() |
| 2 |
虽然将3 个新行插入 t, 对这些行的第一行产生的 ID 为 2, 这也是 LAST_INSERT_ID()返回的值。
第四、假如你使用 INSERT IGNORE而记录被忽略,则AUTO_INCREMENT 计数器不会增量,而 LAST_INSERT_ID() 返回0, 这反映出没有插入任何记录。
一般情况下获取刚插入的数据的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。LAST_INSERT_ID是基于单个connection的, 不可能被其它的客户端连接改变。
##########################################官方文档里的一些说明可以参考以下链接
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
- mysql中的LAST_INSERT_ID
- mysql中的last_insert_id()
- mysql中的last_insert_id()
- mysql中的LAST_INSERT_ID()分析
- mysql中的LAST_INSERT_ID()分析
- MYSQL中的LAST_INSERT_ID()和MSSQL中的@@IDENTITY
- 辛星浅析MySQL中的last_insert_id()
- MYSQL LAST_INSERT_ID()
- mysql last_insert_id();
- mysql的last_insert_id()用法
- 使用MySQL的LAST_INSERT_ID
- 使用MySQL的LAST_INSERT_ID
- 使用MySQL的LAST_INSERT_ID
- MYSQL 小技巧 -- LAST_INSERT_ID
- MySQL的LAST_INSERT_ID用法
- MySQL的LAST_INSERT_ID用法
- mysql的 last_insert_id
- MySQL的LAST_INSERT_ID用法
- Delphi驱动开发研究第三篇--一个完整的驱动程序示例
- loginform
- Checkstyle
- Android:ThreadLearning1
- 每周四十小时,你有多少是在为自己干活?
- mysql中的last_insert_id()
- Delphi驱动开发研究第六篇--与用户进程通讯(section篇)
- c# using用法
- Struts 2+Jquery+JSON(登录验证)
- Delphi驱动开发研究第七篇--与用户进程通讯(共享内存篇)
- Java Reflection 操作实例 (JAVA反射)
- pthread_mutex互斥锁多进程共享
- 网络监听和信息截获,网络安全的思考。
- PHP获取文件后缀名的几种方法