MySQL 插入与自增主键值相等的字段 与 高并发下保证数据准确的实验
2024-08-26 19:12:19
场景描述: 表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文件
<?php
$sql = "INSERT INTO `t2` VALUES(NULL ,(SELECT `AUTO_INCREMENT` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = 'test' AND `TABLE_NAME`='t2'));"; $link = mysql_connect("localhost", "root", "") or die("Could not connect: " . mysql_error());
mysql_select_db("test");
mysql_query($sql);
mysql_close($link);
?>
用ab工具测试
ab -n 50000 -c 20 http://localhost/my.php
结果是:大量的行出现了 v 和 id 不相等的情况(select * from t2 where id != v;)
改写下 PHP
<?php
$sql = "INSERT INTO `t2` VALUES(NULL ,(SELECT `AUTO_INCREMENT` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = 'test' AND `TABLE_NAME`='t2'));"; $link = mysql_connect("localhost", "root", "") or die("Could not connect: " . mysql_error());
mysql_select_db("test");
mysql_query('START TRANSACTION'); #开始事务
mysql_query($sql);
$id = mysql_insert_id();
$res = mysql_query("SELECT `v` FROM `t2` WHERE id= ".$id); if (!$res) {
mysql_close($link);
die;
} $row = mysql_fetch_assoc($res);
if($row['v'] != $id){
mysql_query(' ROLLBACK '); #回滚事务
}
mysql_query('COMMIT'); #提交事务
mysql_close($link);
?>
再使用AB测试,这次速度变慢了 但是结果是都是正确的
最新文章
- npm start 作用
- js中call、apply、bind的用法
- java 从数据删除指定值
- jquery点击获取子元素ID值
- 加载gif动画的三种方式
- 第四篇 SQL Server安全权限
- 华为项目管理10大模板Excel版(可直接套用_非常实用)
- apache日志切割
- windows2003 iis6.0站点打不开,找不到服务器或 DNS 错误。
- hide(1000)跟show(1000)
- 关于Oracle数据库中SQL空值排序的问题
- Sharepoint中用treeview来显示组织机构的人员状态的webpart
- IOS开发之tableview只选中一行
- 【Android】BroadCast广播机制应用与实例
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(19)-权限管理系统-用户登录
- 关于Dubbo分布式服务
- 用scheme最基本的元素定义排序函数
- Redis 攻击还原Linux提权入侵的相关说明
- 开源框架--NFine.Framework学习(01)
- 解读jquery.filtertable.min