MySQL 插入与自增主键值相等的字段 与 高并发下保证数据准确的实验

场景描述: 表t2 中 有 自增主键 id  和 字段v  当插入记录的时候 要求 v与id 的值相等(按理来说这样的字段是需要拆表的,但是业务场景是 只有某些行相等 )

在网上搜的一种办法是 先获取自增ID

SELECT max(id)+1 from t2

然后给v字段插入获取到的值

但是这样的做法在有删除行+调整过自增值的表中是不准确的

于是换个思路 从 information_schema 下手 读取表的信息

INSERT INTO `t2`
VALUES
    (
        NULL,
        (
            SELECT
                `AUTO_INCREMENT`
            FROM
                `information_schema`.`TABLES`
            WHERE
                `TABLE_SCHEMA` = ‘test‘
            AND `TABLE_NAME` = ‘t2‘
        )
    );

功能是实现了 但是真的安全么

于是写个PHP文件

1 <?php
2 $sql  = "INSERT INTO `t2` VALUES(NULL ,(SELECT `AUTO_INCREMENT` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = ‘test‘ AND `TABLE_NAME`=‘t2‘));";
3
4 $link = mysql_connect("localhost", "root", "") or die("Could not connect: " . mysql_error());
5 mysql_select_db("test");
6 mysql_query($sql);
7 mysql_close($link);
8 ?>

用ab工具测试

ab -n 50000 -c 20 http://localhost/my.php

结果是:大量的行出现了 v 和 id 不相等的情况(select * from t2 where  id != v;)

改写下 PHP

 1 <?php
 2 $sql  = "INSERT INTO `t2` VALUES(NULL ,(SELECT `AUTO_INCREMENT` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = ‘test‘ AND `TABLE_NAME`=‘t2‘));";
 3
 4 $link = mysql_connect("localhost", "root", "") or die("Could not connect: " . mysql_error());
 5 mysql_select_db("test");
 6 mysql_query(‘START TRANSACTION‘); #开始事务
 7 mysql_query($sql);
 8 $id = mysql_insert_id();
 9 $res = mysql_query("SELECT `v` FROM  `t2` WHERE id= ".$id);
10
11 if (!$res) {
12     mysql_close($link);
13     die;
14 }
15
16 $row = mysql_fetch_assoc($res);
17 if($row[‘v‘] != $id){
18     mysql_query(‘ ROLLBACK ‘); #回滚事务
19 }
20 mysql_query(‘COMMIT‘); #提交事务
21 mysql_close($link);
22 ?>

再使用AB测试,这次速度变慢了 但是结果是都是正确的

时间: 2024-09-29 22:13:25

MySQL 插入与自增主键值相等的字段 与 高并发下保证数据准确的实验的相关文章

关于mybatis用mysql时,插入返回自增主键的问题

公司决定新项目用mybatis,虽然这个以前学过但是一直没用过都忘得差不多了,而且项目比较紧,也没时间去系统点的学一学,只好很粗略的百度达到能用的程度就行了. 其中涉及到插入实体要求返回主键id的问题,以前用ssh配合oracle很容易实现,因为有sequence,而且mysql也基本没用过,所以只好去百度了. 这个内容还是比较好查的,如下: <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapp

jdbc 预编译处理 和spring返回自增主键值

利用GeneratedKeyHolder获得新建数据主键值 Spring利用GeneratedKeyHolder,提供了一个可以返回新增记录对应主键值的方法 : int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder)//该方法返回受影响的行数,同时将新增记录对应主键值赋值给generatedKeyHolder参数 Spring为KeyHolder接口指代了一个通用的实现类GeneratedKeyHolder,该

mybatis在oracle插入对象后返回主键值

在mybatis中默认插入一条记录后,返回值为插入记录的条数. 现在想获取插入记录后,当前被插入的记录的主键值,需在insert方法中添加如下代码: <insert id="insert" parameterType="cn.com.pm.ppm.model.UserInfo" >   <selectKey resultType="java.math.BigDecimal" order="BEFORE" ke

SQL Server 插入数据后获得自增主键值

通过SQLServer系统自带函数获取 String sql = "insert into goods values('" + TextBox1.Text + "'," + TextBox2.Text + ",0," + TextBox3.Text + ",'','" + DropDownList1.SelectedItem.Text + "','" + Session["username&quo

mycat分布式mysql中间件(自增主键)

一.全局序列号 全局序列号是MyCAT提供的一个新功能,为了实现分库分表情况下,表的主键是全局唯一,而默认的MySQL的自增长主键无法满足这个要求.全局序列号的语法符合标准SQL规范,其格式为:next value for MYCATSEQ_XXXMYCATSEQ_XXX 是序列号的名字,MyCAT自动创建新的序列号,免去了开发的复杂度,另外,MyCAT也提供了一个全局的序列号,名称为:MYCATSEQ_GLOBAL 注意,MYCATSEQ_必须大写才能正确识别.MyCAT温馨提示:实践中,建议

sql语句修改mysql表的自增主键

我们在开发过程中,会用到一些初始化语句,由于外键关系,我们需要把某一些ID写死,那么当我们初始化完毕后,需要将Mysql中的表的自增主键从某一个值开始递增. alter table `system_role_menu` AUTO_INCREMENT = 11; 上述表表示,system_role_menu表从11开始递增,下一个插入的值的主键为11.

mybatis中useGeneratedKeys用法--插入数据库后获取主键值

前言:今天无意在mapper文件中看到useGeneratedKeys这个词,好奇就查了下,发现能解决我之前插入有外键表数据时,这个外键获取繁琐的问题,于是学习敲DEMO记录    在项目中经常需要获取到插入数据的主键来保障后续操作,数据库中主键一般我们使用自增或者uuid()的方式自动生成 问题:对于uuid使用Java代码生成的方式还比较容易控制,然而使用数据库生成的主键,这样我们就需要将插入的数据再查询出来得到主键,某些情况下还可能查询到多条情况,这样就比较尴尬了. 那有什么办法来插入数据

Mybatis批量插入返回自增主键(转)

我们都知道Mybatis在插入单条数据的时候有两种方式返回自增主键: 1.对于支持生成自增主键的数据库:useGenerateKeys和keyProperty. 2.不支持生成自增主键的数据库:<selectKey>. 但是怎对批量插入数据返回自增主键的解决方式网上看到的还是比较少,至少百度的结果比较少. Mybatis官网资料提供如下: First, if your database supports auto-generated key fields (e.g. MySQL and SQL

mybatis insert语句 返回插入的记录的主键值

Map<String,Object> paymentMp = new HashMap<String,Object>();        paymentMp.put("amount", 12.0 );        paymentMp.put("pay", Attributes.Payment_Pay_No);        paymentMp.put("status", Attributes.Payment_Status_