mysql返回自增id

这篇博客探讨了MySQL中如何使用用户变量进行行编号,并在查询中实现数据排序。通过示例展示了(@i:=@i+1)inx的用法,以及如何在查询后重置变量。文章详细解释了用户变量的定义、赋值方法及其在查询中的作用,特别是对于数据处理和分析的场景。

SELECT (@i:=@i+1) inx,
        others,savetime

    FROM
        t_data, (SELECT @i:=0) as inx 
    where
        siteid =...
    order by
        savetime asc


分析: 
在开始是定义一个变量i,让它每增一条结果是+1,@i:=1; 
这里顺带复习下mysql定义用户变量的方式:select @变量名 
对用户变量赋值有两种方式,一种是直接用”=”号,另一种是用”:=”号。其区别在于使用set命令对用户变量进行赋值时,两种方式都可以使用;当使用select语句对用户变量进行赋值时,只能使用”:=”方式,因为在select语句中,”=”号被看作是比较操作符 
(@i:=@i+1) 也可以写成 @i:=@i+1,加括号是为了视觉上看这结构更清楚些。在定义好一个变量后每次查询都会给这个变量自增,而我们每次执行查询语句获取结果后就不需要这个变量自增了,所以要把它重置为0,在表名后用逗号分格下使用 (SELECT @i:=0) as i 就可以了,说下这个as i为什么要这样用,是因为派生表必须需要一个别名,这个就是做它的别名,可以任意字符。 
 

<think> 我们正在讨论MySQL中INSERT语句插入数据后返回ID的方法。根据引用资料,主要有以下几种方法: 1. **使用`LAST_INSERT_ID()`函数**: - 在插入语句后立即执行`SELECT LAST_INSERT_ID();`即可获得自ID。 - 该函数基于当前连接(Connection),因此即使其他连接同时插入数据也不会影响结果。 - 注意:如果一次插入多行,返回的是第一个插入行的自ID(不是列表)[^1][^4]。 2. **在编程中使用特定方式获取**(如MyBatis): - 在MyBatis的Mapper XML中,使用`useGeneratedKeys="true"`和`keyProperty="id"`(其中id为对象属性),插入后自ID会自动填充到参数对象的对应属性中[^2]。 - 另一种方式是使用`<selectKey>`标签,在插入后通过`SELECT LAST_INSERT_ID()`获取并填充到对象属性[^4]。 3. **使用`max(id)`(不推荐)**: - 通过`SELECT MAX(id) FROM table;`获取最大ID。但高并发时可能不准,且不适合多线程环境[^3]。 --- ### 详细说明与代码示例 #### 方法1:使用`LAST_INSERT_ID()`(适用于命令行或脚本) ```sql -- 插入单条数据 INSERT INTO user (name, age) VALUES ('张三', 18); -- 获取自ID SELECT LAST_INSERT_ID(); ``` **注意**:批量插入时,`LAST_INSERT_ID()`返回的是**第一条**记录的自ID[^4]。 #### 方法2:在MyBatis中映射自ID(Java应用) ```xml <!-- 方式1:useGeneratedKeys --> <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user(name, age) VALUES(#{name}, #{age}) </insert> <!-- 方式2:selectKey --> <insert id="insertUser" parameterType="User"> <selectKey resultType="java.lang.Long" keyProperty="id" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> INSERT INTO user(name, age) VALUES(#{name}, #{age}) </insert> ``` 插入后,传入的`User`对象的`id`属性会自动赋值。 #### 方法3:其他编程语言(如PHP) ```php <?php $pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass"); $stmt = $pdo->prepare("INSERT INTO user (name, age) VALUES (?, ?)"); $stmt->execute(['李四', 20]); $id = $pdo->lastInsertId(); // 直接获取自ID echo $id; ?> ``` --- ### 注意事项 1. **连接独立性**:`LAST_INSERT_ID()`只对当前连接有效,不同连接互不影响[^1]。 2. **批量插入**:插入多行时,只能获取第一条的自ID,其余ID需通过计算获得(如插入$n$条,则后续ID为`LAST_INSERT_ID()+1`至`LAST_INSERT_ID()+n-1`)[^4]。 3. **事务安全**:自ID在事务提交前即可获取,但若事务回滚,该ID会被废弃(可能导致跳号)[^3]。 --- ### 相关问题 1. MySQL的`LAST_INSERT_ID()`在批量插入时如何处理? 2. 不同数据库连接同时插入数据,`LAST_INSERT_ID()`会互相影响吗? 3. 使用MyBatis插入数据后,如何获取非自主键(如UUID)的值? 4. 高并发场景下,使用`max(id)`获取自ID有什么风险? > 引用说明:`LAST_INSERT_ID()`原理来自MySQL官方文档[^1];MyBatis配置方法参考ORM框架实践[^2][^4];`max(id)`的缺陷分析源于并发场景经验[^3]。 </think> ### MySQL 中 INSERT 语句返回 ID 的完整方法 在 MySQL 中获取 INSERT 操作后的自 ID 主要有以下几种方法,根据使用场景选择最适合的方式: #### ✅ 方法 1:使用 `LAST_INSERT_ID()` 函数(通用推荐) ```sql INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com'); SELECT LAST_INSERT_ID(); -- 立即执行此查询获取自 ID ``` **原理** - 基于当前数据库连接(Connection)返回最近一次 INSERT 生成的自 ID[^1][^3] - 线程安全:不同连接互不影响(无需担心并发冲突)[^3] - 批量插入时返回第一条数据的 ID[^4] **适用场景**:命令行操作、存储过程或脚本场景 #### ✅ 方法 2:MyBatis 映射配置(Java 应用首选) ```xml <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO users(name, email) VALUES(#{name}, #{email}) </insert> ``` **执行后效果**: ```java User user = new User("李四", "lisi@example.com"); userMapper.insertUser(user); System.out.println(user.getId()); // 自ID自动注入到对象属性 ``` **备选方案**(兼容更多 ORM): ```xml <insert id="insertUser" parameterType="User"> <selectKey resultType="java.lang.Long" keyProperty="id" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> INSERT INTO users(name, email) VALUES(#{name}, #{email}) </insert> ``` [^2][^4] #### ✅ 方法 3:编程语言原生支持(各语言示例) **PHP (PDO)**: ```php $stmt = $pdo->prepare("INSERT INTO users(name, email) VALUES(?, ?)"); $stmt->execute(['王五', 'wangwu@example.com']); echo $pdo->lastInsertId(); // 直接获取自ID ``` **Python (PyMySQL)**: ```python cursor.execute("INSERT INTO users(name, email) VALUES(%s, %s)", ('赵六', 'zhaoliu@example.com')) print(cursor.lastrowid) # 获取自ID ``` #### ⚠️ 不推荐方法:使用 `MAX(id)` ```sql SELECT MAX(id) FROM users; -- 高并发时可能返回错误值 ``` **缺点**: - 并发插入时可能获取到其他会话的 ID - 需要表级锁影响性能[^3] --- ### 关键注意事项 1. **事务中的行为** - 自 ID 在事务提交前即可获取 - 事务回滚时 ID 会被丢弃(导致 ID 不连续) 2. **批量插入处理** ```sql INSERT INTO users(name) VALUES('A'),('B'),('C'); SELECT LAST_INSERT_ID(); -- 返回 A 的 ID ``` 获取后续 ID:`LAST_INSERT_ID() + 1` 到 `LAST_INSERT_ID() + 2`[^4] 3. **连接池配置** 确保 ORM 框架使用后**立即释放连接**,避免 `LAST_INSERT_ID()` 返回其他操作的 ID --- ### 相关问题 1. 批量插入 100 条数据时,如何高效获取所有自 ID? 2. 使用数据库连接池时,`LAST_INSERT_ID()` 可能返回错误值如何解决? 3. 在分布式系统中,MySQL ID 会有什么问题?替代方案是什么? 4. 事务回滚导致的自 ID 跳跃对业务有什么影响?如何避免? > 引用说明:`LAST_INSERT_ID()` 的线程安全特性基于 MySQL 官方文档 [^1][^3];MyBatis 配置实践参考 ORM 框架最佳实践 [^2][^4];`MAX(id)` 的缺陷分析源于高并发场景测试 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值