- 浏览: 208529 次
- 性别:
- 来自: 重庆
-
文章分类
最新评论
刚才查了下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表'
;
|
字段‘name’用来说明这个ID是哪个业务的,比如‘用户’的ID,我们可以定为‘USER’;
字段‘value’即该业务的ID值。
2、初始化业务和其ID值
INSERT
INTO
ticket_mutex(
name
, value)
values
(
'USER'
,
0),(
'POST'
, 0);
|
+
------+-------+
|
|
name
| value |
|
+
------+-------+
|
| POST | 0 |
|
|
USER
| 0 |
|
+
------+-------+
|
我们初始化了2条记录,即有2个不同的业务,分别代表‘用户信息’和‘主题信息’,它们初始ID值均为‘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 |
|
+
------------------+
|
通过这条语句之后,我们得到结果为1,这个值就是我们所需要的值。再来查看数据记录,我们发现记录总数没有改变,但是‘用户’的ID已经为1了;
+
------+-------+
|
|
name
| value |
|
+
------+-------+
|
| POST | 0 |
|
|
USER
| 1 |
|
+
------+-------+
|
同样的方法,我们可获取‘主题’的ID:
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()为‘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的SQL_CALC_FOUND_ROWS
2012-12-17 16:44 1435FOUND_ROWS() 函数 ,可以在调用包含LIMIT的 ... -
innodb的记录锁、gap锁、next-key锁
2012-12-17 13:45 1431相关文章见: http://dev.mysql ... -
MySQL Innodb表死锁情况分析与归纳(转载)
2012-12-14 16:22 1997案例描述 在定时脚本运行过程中,发现当 ... -
MySQL连接超时
2012-12-13 20:41 1154在负载较重的MySQL服务器上,有时你偶尔会看到一些 ... -
mysql优化索引 —— Using filesort
2012-12-11 12:13 862用Explain分析SQL语句的时候,经常发现有的语句在 ... -
IN条件结果顺序问题
2012-11-23 14:42 714项目中需要记录用户的浏览历史,我的意见是前端直接存cook ... -
mysql那点事(行锁+not null + varchar)
2012-10-12 15:08 1716一。not null vs DEAFUL value ... -
关于mysql auto_increment所带来的锁表操作
2012-09-01 14:00 1641以前内容主要是对官方文档中的意译,并加入了一些自己的理解 ... -
mysql 与unicode
2012-08-29 15:36 1739UTF8字符集(转换Unicode表示)是存储Unico ... -
深入Mysql字符集设置
2012-08-29 14:46 59105 Jan 08 深入Mysql字符集设置 ... -
关于set names
2012-08-29 14:37 839<?php$conn=mysql_connect( ... -
MYSQL索引优化和in or替换为union all
2012-08-22 17:16 4085一个文章库,里面有两个表:category和article。c ... -
mysql读写分离(PHP类)
2012-08-18 18:08 3763自己实现了php的读写 ... -
mysql分表的3种方法
2012-08-02 14:39 867当一张的数据达到几百万时,你查询一次所花的时间会变多,如 ... -
MySql BLOB类型
2012-08-02 13:42 762MySql的Bolb四种类型 MySQL中,BLOB是一个二进 ... -
MySQL 查询优化技巧
2012-07-18 20:26 791瓶颈 众所周知,几乎所有大型项目的最终效率瓶颈,都来自 ... -
mysql多表联合查询
2012-07-18 19:16 1684我在工作中天天研究zen cart的程序,那个叫人痛苦,最近比 ...
相关推荐
在MySQL数据库中,LAST_INSERT_ID()函数是一个非常实用的工具,尤其在处理多表关联或者需要获取最新插入记录的自增ID时。该函数的主要作用是返回最近一次执行的INSERT或UPDATE语句对具有AUTO_INCREMENT属性的列所...
MySQL数据库管理系统中,LAST_INSERT_ID() 函数和 mysql_insert_id() 函数都可以用来获取最近一次INSERT操作生成的自增ID值。在PHP开发中,正确地使用这两个函数对于确保数据一致性及避免并发问题至关重要。本知识...
标题提到的"MYSQL 小技巧 — LAST_INSERT_ID"着重讨论了MySQL中获取自增ID的两种方法:`LAST_INSERT_ID()`和`mysql_insert_id()`的区别以及它们在不同情况下的适用性。 首先,`LAST_INSERT_ID()`函数是MySQL提供的...
在MySQL中,`last_insert_id()`是一个用于获取最后通过`INSERT`语句生成的自增ID的函数,尤其在自增主键列上非常有用。在大多数情况下,当你插入一条新记录并需要获取这个新生成的ID时,这个函数会派上用场。 在...
为了更准确地获取多行插入后的自增ID,可以使用`LAST_INSERT_ID()`配合`INSERT INTO ... VALUES ...`语句的子查询形式,或者在每个插入操作之后立即调用`LAST_INSERT_ID()`,确保每次都获取到单次插入操作的ID。 ...
`LAST_INSERT_ID()`函数同样返回最后一条插入记录的自增ID,且只对当前连接有效。这意味着它能够处理`bigint`类型的ID,解决了`mysql_insert_id()`的局限性。 综合来看,推荐使用`mysql_insert_id()`函数作为首选...
- 如果你的应用环境中允许使用`LAST_INSERT_ID()`函数,可以通过执行如下SQL语句来获取最后插入记录的ID。 ```java Statement stmt = connection.createStatement(); stmt.executeUpdate("INSERT INTO test_...
创建一个只含有自增ID字段的表,如`test`,使用MyISAM引擎(因为它对`LAST_INSERT_ID()`支持更好)。通过`UPDATE`语句将ID设置为其自身的值加1,然后使用`SELECT LAST_INSERT_ID();`获取新生成的ID。`LAST_INSERT_...
Java获取新insert数据自增id的实现方法可以通过select LAST_INSERT_ID()或使用Statement的getGeneratedKeys方法来实现。这两种方法都可以解决获取新insert数据自增id的问题,而select LAST_INSERT_ID()方法更加简洁...
函数返回的是上一个INSERT操作产生的自增ID。如果最近的查询没有生成自增ID,函数会返回0。 **参数描述** - `$connection`:可选参数,指定MySQL连接资源。如果省略,将使用最近的已打开的连接。 **提示和注释** -...
与`LAST_INSERT_ID()`不同,`@@IDENTITY`是一个全局变量,它会返回最近一次向任何具有`identity`属性(即自增列)的表插入数据时对应的自增列值。但是,使用`@@IDENTITY`的一个关键点是,必须在执行`INSERT`操作后并...
- **标准方法:** 使用`INSERT`语句插入数据后,可以通过`LAST_INSERT_ID()`函数或`getGeneratedKeys()`方法来获取刚插入记录的自增ID。 - **示例代码:** 下面的Java示例展示了如何使用JDBC API来插入一条记录并...
4. **last_insert_id()函数**: - 该函数用于获取自增列自动生成的最后一个编号,仅与当前会话相关。如果没有生成新的自增值,返回0。 5. **多序列自增**: - 在MyISAM之外的数据表类型中,如InnoDB,可以通过...
一种可能的解决方案是使用`LAST_INSERT_ID()`函数配合`SELECT...FOR UPDATE`语句。当多个并发线程尝试获取新的ID时,每个线程都会锁定表中的特定行,然后通过`LAST_INSERT_ID()`获取当前的ID并增加它。这样可以确保...
MySQL提供了`LAST_INSERT_ID()`函数,可以返回最近一次由`INSERT`或`UPDATE`语句产生的自增值。同样,`@@IDENTITY`变量也提供类似的功能。这两个方法都是针对当前会话的,因此在单个连接中是线程安全的。但是,需要...