MYSQL报错语句讲解
MYSQL报错语句很多,但是了解其原理才是做重要的
让我们先看一段报错语句
select count(*),(floor(rand(0)*2))x from information_schema.tables group by x
这条报错的语句最重要的部分有三个:
- rand(0)
- floor()
- group by
现在我就讲一下这三个部分
一、rand(0)
rand()是用来产生随机数的,他的范围是[0,1]之间
可以看到每一次的数值都是不同的
而且rand()有一个BUG,报错也就是利用了这个BUG,这个后面会细说,暂时就理解产生随机数就好了
二、floor()
floor()是用来取整的,重点:没有四舍五入
这样一来用floor()来包裹着rand()岂不是没有用了吗?因为结果一定会是0。
所以我们要对rand()进行处理,那就是对他乘个2,这样就会出现1。
这样子我们会有个疑问,因为是rand()是随机的所以出现0,1也是随机的,是不可控的,可以看到确实是随机的
所以我们要对rand()做一点点修改,将rand()加个0,变成rand(0)
加一个0以后的我们发现数字的结果就唯一,是01101,这串数字特别的重要,我们的报错就是来自于他重要的事情说三遍:01101,01101,01101
三、group by
为了演示方便我创建了一个test表
接下来我们用一下group by 看看有什么作用
select * from test group by age;
可以看到 group by 创建了一个新的虚空的表,并且以 by 后的字段 age 来查询test表,如果重复了就不再添加,而且新的虚拟表的主键是 by 后面的字段,这就是上图中的 age 。(ps:一个表中主键是不能重复的)
现在就要进入重点了,在此之前我再介绍一下count()
count()函数允许对表中符合特定条件数的所有行进行计数,举个例子
select count(*) from test group by age;
用count(),可以清楚的知道表中,几个15岁,几个18岁,几个19和20岁。
OK,现在我们开始
我们来看这个语句
select count(*) from test group by floor(rand(0)*2);
会注意到是不是和文章开始的报错语句不太一样,其实文章开始的那个报错语句是这个的变形而已,为了更直观咱们就看这个。
还记得我之前说的 rand() 的一个小BUG吗,那就是
就是查询的时候如果使用rand()的话,该值会被计算多次,这个是MySql官方说的,这个“多次计算”在咱的报错语句中来解读就是,group by floor(rand(0)*2)
在执行是会计算一次 floor(rand(0)*2)
,但是在插入数据时还会执行一次floor(rand(0)*2)
。
还有一个,我在提醒一次 floor(rand(0)*2)
的前5个计算结果为 01101
语句开始运行
- group by 以
floor(rand(0)*2)
为主键,建立一个虚拟的空表 keycount - 查询第一条记录,计算
floor(rand(0)*2)
(这是第一次计算),得到的值是0,查看表发现没有0,所以进行插入操作,但是在插入时又会计算一次floor(rand(0)*2)
(这是第二次计算)结果为1,此时的表为 keycount 11 - 查询第二条记录,计算
floor(rand(0)*2)
(这是第三次计算),得到值是1,查看表发现已经有了,则不进行插入操作,直接count+1,此时表为 keycount 12 - 查询滴三条记录,计算
floor(rand(0)*2)
(这是第四次计算),得到的是0,查看表发现没有,进行插入操作,但是在插入之前会在此计算floor(rand(0)*2)
(这是第五次计算),得到的是1。然而表中已经有key为1 ,所以会产生报错。 keycount 12 1 (出错)
总结
出现报错的原因是,因为已经要执行插入数据操作,才发现了主键冲突。
这个报错是利用 rand() 的特殊性,以及floor(rand(0)*2)
前5个数字的可预知性,以及可以通过 group by 来创建一个空的虚拟表,这些条件综合在一起产生的报错。
Q.E.D.
相关文章
- mysql语句怎么拼接字符串_MySQL执行拼接字符串语句实例[通俗易懂]
- MySQL创建表:SQL语句实现(mysql创建表的sql语句)
- 深入理解MySQL关系模型(mysql关系模型)
- 使用 MySQL 子语句简化数据库查询(mysql子语句)
- MySQL存储汉字的类型研究(mysql汉字类型)
- MySQL用户手册:解读数据库管理的完美结合(mysql用户手册)
- MySQL操作: 学习基础SQL语句(mysql的操作语句)
- MySQL操作:增删改查语句详解(mysql增删改查语句)
- MySQL语句删除操作的正确姿势:25字带你掌握!(mysql语句删除)
- MySQL存储过程报错:如何排查与解决?(mysql存储过程报错)
- 什么MySQL语句:创建新表格(创建mysql的语句是)
- MySQL中的辛星:挑战传统的外表与现代的内涵(辛星mysql)
- MySQL的高效使用:多条查询语句优化详解(mysql多条查询语句)
- MySQL语句分析:彻底了解你的查询(mysql 语句分析)
- MySQL修改数据语句详解(mysql中修改数据语句)
- 提高数据库操作效率MySQL实现两表索引(mysql 两表索引)
- MySQL 两表关联语句详解,快速提升SQL语言水平(mysql 两表关联语句)
- 使用ADO MySQL记录集创建数据库应用(ado mysql记录集)
- 用CMD命令快速进入MySQL(cmd如何进入mysql)
- MySQL 判断语句的使用方法简介(mysql中判断怎么写)
- MySQL中关联查询语句详解(mysql中关联查询语句)
- 使用MySQL循环执行一组语句(mysql一组语句循环)
- 使用MySQL进行一位整数运算简单易学,快速高效(mysql 一位整数)
- 如何在MySQL中停止服务(mysql下关闭服务)
- 写出 SQL 语句时,MySQL 无法识别大小写(mysql不能识别大小)
- 解决MySQL枚举类型无法使用的问题(mysql不能用enum)