您现在的位置是:首页 > 教程资讯

Mysql报错引入之floor(rand(0)*2)报错基本原理研究

作者:果E安全网时间:2020-10-25 22:28:54分类:教程资讯

简介floor报错引入是运用这一相对性固定不动的句子文件格式,造成的数据库查询报错。具体运用中根据concat涵数,联接引入句子与floor(rand(0)*2)涵数,就完成了引入結果与报错信息内容回显的引入方法。实际运用文中不做论述,文

floor报错引入是运用 这一相对性固定不动的句子文件格式,造成 的数据库查询报错。具体运用中根据 concat 涵数,联接引入句子与 floor(rand(0)*2)涵数,就完成了引入結果与报错信息内容回显的引入方法。实际运用文中不做论述,文中关键研究该句子报错的缘故,要了解该句子的报错缘故,最先大伙儿必须了解以下的重要涵数的功效: count() 、group by 、floor()、rand()。

rand() 是一个随机函数,根据一个固定不动的随机数字的種子0以后,能够产生固定不动的伪随机编码序列。結果如下图所显示:

由此可见,立即应用rand涵数每一次造成的数都不一样,可是当出示了一个固定不动的随机数字的種子0以后:

那样每一次造成的值全是一样的。还可以称作伪随机(造成的数据信息全是可预料的)。

查询好几个数据信息看一下。(users是一个有6行数据信息的表)

图片.png那样第一次造成的随机数字和第二次彻底一样,也就是能够预测分析的。

那麼floor报错引入运用的情况下rand(0)*2为何要乘于 2 呢?这就需要相互配合floor 涵数而言了。

floor() 涵数的功效便是回到不大于括弧内该值的较大 整数金额,也就是求整。

floor(rand(0)*2)便是对rand(0)造成的任意编码序列诚心2后的結果,再开展求整。获得伪随机编码序列为如下图所显示:

图片.png由于应用了固定不动的随机数种子0,他每一次造成的随机数字列全是同样的0 1 1 0 1 1的次序。

group by 关键用于对数据信息开展排序(同样的分成一组)。

比如创建以下表开展试验

图片.png

根据以下句子开展查看。(这儿在a和x以前默认设置了as ,功效为用a和x替代原来的字段名显示信息),显示信息的結果如下图所显示:

图片.png但根据group by开展排序排列是,結果会开展排序,同样姓名为合拼。如下图所显示

留意:最终x这列中显示信息的每一类仅有一次,前边的a的是第一次出現的id值

图片.png

count(*)统计分析結果的纪录数。

这儿与group by融合应用看一下:

图片.png这儿便是对a中的可重复性的数据信息开展了融合,随后记数,后边的x便是每一类的总数。也就是lisi有两个,wangwu有一个,zhangsan有3个。留意显示信息一样是依照ascii排列。

大伙儿早已掌握,当实行以下句子时,便会造成一个报错。如下图所显示

select count(*),floor(rand(0)*2) x from users group by x;

图片.png

依据前边涵数的了解,这句话本意便是统计分析后边产生随机数的类型并计算每个总数。本来实行結果一共6行数据信息,造成的任意编码序列应当为0 1 1 0 1 1 ,依照句子的含意,统计分析假如应该是:0是两个,1是4个,可是这里却造成了报错?这是为什么呢?下边来剖析一下。

这儿最重要的立即要了解group by涵数的工作中全过程。group by key 在实行时循环系统获取数据的每一行,将結果储存于临时表中。载入每一行的key时,假如key存有于临时表中,则升级临时表中的数据信息(升级数据信息时,已不计算rand值);假如该key不会有于临时表中,则在临时表中插进key所属行的数据信息。(插进数据信息时,会再计算rand值)

假如这时临时表仅有key为1的行不会有key为0的行,那麼数据库查询要将此条纪录插进临时表,因为是随机数字,插时又要计算一下任意值,这时 floor(random(0)*2)結果很有可能为1,便会造成 插进时矛盾而报错。即检验时和插进时2次计算了随机数字的值。

实际报错缘故能够根据下述全过程展现:

mysql实行結果,会造成 011011 这一编码序列,group by时,会创建空虚似表如下图,随后从sql语句实行結果编码序列(011011)获取数据并插进虚表:

图片.png(1)虚表载入第一条纪录,实行floor(rand(0)*2),发觉結果为0(这时为第一次计算)

图片.png(2)查看虚似表,发觉0的键值不会有,则插进新的键值的情况下floor(rand(0)*2)会被再计算一次,結果为1(这时为第二次计算),插进虚表,第一条纪录插进结束,結果为1。如下图:

图片.png

(3)虚表载入第二条纪录,再度计算floor(rand(0)*2),发觉結果为1(这时为第三次计算),这时清算結果为1,因此 floor(rand(0)*2)不容易被计算,立即count(*)加1,第二条纪录载入结束。(5)查看虚表,发觉1的键值存有,因此 floor(rand(0)*2)不容易被计算第二次,立即count(*)加1,第二条查询记录结束,結果以下:

图片.png(4)虚表载入第三条纪录,再度计算floor(rand(0)*2),发觉結果为0(这时为第4次计算),计算結果为0,这时虚表中沒有0的数据信息纪录,则实行插进该数据信息,插进的时候会再度计算floor(rand(0)*2)(这时为第5次计算),计算結果为1。殊不知1这一主键早已存有于虚似表格中,而新计算的值也为1(主键键值务必唯一),因此 就造成了主键矛盾的不正确,也就是:Duplicate entry 的报错。图片.png汇总:根据所述剖析,在虚表中载入第三条纪录是时,造成了报错。这时floor(rand(0)*2)一共被计算了5次,这也表述了为何数据分析表中必须至少3条数据信息才会报错的缘故。

此外,要留意添加随机数种子的难题,假如没添加随机数种子或是添加别的的数,那麼floor(rand()*2)造成的编码序列是不能测的,那样很有可能会出現一切正常插进没法报错的状况。最重要的是前边几个查询记录后不可以让虚表存有0,1键值,假如存有了,那不管是多少条纪录,也都没法报错,由于floor(rand()*2)不容易再被计算作为虚表的键值,这也就是为什么不加随机数种子有时会报错,有时不容易报错的缘故。

例如下边用1做为随机数种子,就不容易造成报错:

图片.png

图片.png

郑重声明:

果E安全网所有活动均为互联网所得,如有侵权请联系本站删除处理,转载请注明本站地址。

我来说两句