游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

眼见为实,来瞧瞧MySQL中的隐藏列

  在介绍mysql的多版本并发控制MVCC的过程中,我们提到过mysql中存在一些隐藏列,例如行标识、事务ID、回滚指针等,不知道大家是否和我一样好奇过,要怎样才能实际地看到这些隐藏列的值呢?
  本文我们就来重点讨论一下诸多隐藏列中的行标识DBROWID,实际上,将行标识称为隐藏列并不准确,因为它并不是一个真实存在的列,DBROWID实际上是一个非空唯一列的别名。在拨开它的神秘面纱之前,我们看一下官方文档的说明:
  IfatablehasaPRIMARYKEYorUNIQUENOTNULLindexthatconsistsofasinglecolumnthathasanintegertype,youcanuserowidtorefertotheindexedcolumninSELECTstatements
  简单翻译一下,如果在表中存在主键或非空唯一索引,并且仅由一个整数类型的列构成,那么就可以使用SELECT语句直接查询rowid,并且这个rowid的值会引用该索引列的值。
  着重看一下文档中提到的几个关键字,主键、唯一索引、非空、单独一列、数值类型,接下来我们就要从这些角度入手,探究一下神秘的隐藏字段rowid。1、存在主键
  先看设置了主键且是数值类型的情况,使用下面的语句建表:CREATETABLEtable1(idbigint(20)NOTNULLPRIMARYKEY,namevarchar(32)DEFAULTNULL)ENGINEInnoDB;
  插入三条测试数据后,执行下面的查询语句,在select查询语句中直接查询rowid:select,rowidfromtable1
  查看执行结果,rowid可以被正常查询:
  可以看到在设置了主键,并且主键字段是数值类型的情况下,rowid直接引用了主键字段的值。对于这种可以被select语句查询到的的情况,可以将其称为显式的rowid。
  回顾一下前面提到的文档中的几个关键字,再考虑其他情况。由于主键必定是非空字段,下面来看一下主键是非数值类型字段的情况,建表如下:CREATETABLEtable2(idvarchar(20)NOTNULLPRIMARYKEY,namevarchar(32)DEFAULTNULL)ENGINEInnoDB;
  在table2执行上面相同的查询,结果报错无法查询rowid,也就证明了如果主键字段是非数值类型,那么将无法直接查询rowid。
  2、无主键,存在唯一索引
  上面对两种类型的主键进行了测试后,接下来我们看一下当表中没有主键、但存在唯一索引的情况。首先测试非空唯一索引加在数值类型字段的情况,建表如下:CREATETABLEtable3(idbigint(20)NOTNULLUNIQUEKEY,namevarchar(32))ENGINEInnoDB;
  查询可以正常执行,并且rowid引用了唯一索引所在列的值:
  唯一索引与主键不同的是,唯一索引所在的字段可以为NULL。在上面的table3中,在唯一索引所在的列上添加了NOTNULL非空约束,如果我们把这个非空约束删除掉,还能显式地查询到rowid吗?下面再创建一个表,不同是在唯一索引所在的列上,不添加非空约束:CREATETABLEtable4(idbigint(20)UNIQUEKEY,namevarchar(32))ENGINEInnoDB;
  执行查询语句,在这种情况下,无法显式地查询到rowid:
  和主键类似的,我们再对唯一索引被加在非数值类型的字段的情况进行测试。下面在建表时将唯一索引添加在字符类型的字段上,并添加非空约束:CREATETABLEtable5(idbigint(20),namevarchar(32)NOTNULLUNIQUEKEY)ENGINEInnoDB;
  同样无法显示的查询到rowid:
  针对上面三种情况的测试结果,可以得出结论,当没有主键、但存在唯一索引的情况下,只有该唯一索引被添加在数值类型的字段上,且该字段添加了非空约束时,才能够显式地查询到rowid,并且rowid引用了这个唯一索引字段的值。3、存在联合主键或联合唯一索引
  在上面的测试中,我们都是将主键或唯一索引作用在单独的一列上,那么如果使用了联合主键或联合唯一索引时,结果会如何呢?还是先看一下官方文档中的说明:
  rowidreferstothePRIMARYKEYcolumnifthereisaPRIMARYKEYconsistingofasingleintegercolumn。IfthereisaPRIMARYKEYbutitdoesnotconsistofasingleintegercolumn,rowidcannotbeused。
  简单来说就是,如果主键存在、且仅由数值类型的一列构成,那么rowid的值会引用主键。如果主键是由多列构成,那么rowid将不可用。
  根据这一描述,我们测试一下联合主键的情况,下面将两列数值类型字段作为联合主键建表:CREATETABLEtable6(idbigint(20)NOTNULL,nobigint(20)NOTNULL,namevarchar(32),PRIMARYKEY(id,no))ENGINEInnoDB;
  执行结果无法显示的查询到rowid:
  同样,这一理论也可以作用于唯一索引,如果非空唯一索引不是由单独一列构成,那么也无法直接查询得到rowid。这一测试过程省略,有兴趣的小伙伴可以自己动手试试。4、存在多个唯一索引
  在mysql中,每张表只能存在一个主键,但是可以存在多个唯一索引。那么如果同时存在多个符合规则的唯一索引,会引用哪个作为rowid的值呢?老规矩,还是看官方文档的解答:
  Otherwise,rowidreferstothecolumninthefirstUNIQUENOTNULLindexifthatindexconsistsofasingleintegercolumn。IfthefirstUNIQUENOTNULLindexdoesnotconsistofasingleintegercolumn,rowidcannotbeused。
  简单翻译一下,如果表中的第一个非空唯一索引仅由一个整数类型字段构成,那么rowid会引用这个字段的值。否则,如果第一个非空唯一索引不满足这种情况,那么rowid将不可用。
  在下面的表中,创建两个都符合规则的唯一索引:CREATETABLEtable82(idbigint(20)NOTNULL,nobigint(20)NOTNULL,namevarchar(32),UNIQUEKEY(no),UNIQUEKEY(id))ENGINEInnoDB;
  看一下执行查询语句的结果:
  可以看到rowid的值与no这一列的值相同,证明了rowid会严格地选取第一个创建的唯一索引作为它的引用。
  那么,如果表中创建的第一个唯一索引不符合rowid的引用规则,第二个唯一索引满足规则,这种情况下,rowid可以被显示地查询吗?针对这种情况我们建表如下,表中的第一个索引是联合唯一索引,第二个索引才是单列的唯一索引情况,再来进行一下测试:CREATETABLEtable9(idbigint(20)NOTNULL,nobigint(20)NOTNULL,namevarchar(32),UNIQUEKEYindex1(id,no),UNIQUEKEYindex2(id))ENGINEInnoDB;
  进行查询,可以看到虽然存在一个单列的非空唯一索引,但是因为顺序选取的第一个不满足要求,因此仍然不能直接查询rowid:
  如果将上面创建唯一索引的语句顺序调换,那么将可以正常显式的查询到rowid。5、同时存在主键与唯一索引
  从上面的例子中,可以看到唯一索引的定义顺序会决定将哪一个索引应用rowid,那么当同时存在主键和唯一索引时,定义顺序会对其引用造成影响吗?
  按照下面的语句创建两个表,只有创建主键和唯一索引的顺序不同:CREATETABLEtable11(idbigint(20)NOTNULL,nobigint(20)NOTNULL,PRIMARYKEY(id),UNIQUEKEY(no))ENGINEInnoDB;CREATETABLEtable12(idbigint(20)NOTNULL,nobigint(20)NOTNULL,UNIQUEKEY(id),PRIMARYKEY(no))ENGINEInnoDB;
  查看运行结果:
  可以得出结论,当同时存在符合条件的主键和唯一索引时,无论创建顺序如何,rowid都会优先引用主键字段的值。6、无符合条件的主键与唯一索引
  上面,我们把能够直接通过select语句查询到的称为显式的rowid,在其他情况下虽然rowid不能被显式查询,但是它也是一直存在的,这种情况我们可以将其称为隐式的rowid。
  实际上,innoDB在没有默认主键的情况下会生成一个6字节长度的无符号数作为自动增长的rowid,因此最大为2481,到达最大值后会从0开始计算。下面,我们创建一个没有主键与唯一索引的表,在这张表的基础上,探究一下隐式的rowid。CREATETABLEtable10(idbigint(20),namevarchar(32))ENGINEInnoDB;
  首先,我们需要先查找到mysql的进程pid:psefgrepmysqld
  可以看到,mysql的进程pid是2068:
  在开始动手前,还需要做一点铺垫,在innoDB中其实维护了一个全局变量dictsys。rowid,没有定义主键的表都会共享使用这个rowid,在插入数据时会把这个全局rowid当作自己的主键,然后再将这个全局变量加1。
  接下来我们需要用到gdb调试的相关技术,gdb是一个在Linux下的调试工具,可以用来调试可执行文件。在服务器上,先通过yuminstallgdb安装,安装完成后,通过下面的gdb命令把rowid修改为1:gdbp2068expdictsysrowid1batch
  命令执行结果:
  在空表中插入3行数据:INSERTINTOtable10VALUES(100000001,Hydra);INSERTINTOtable10VALUES(100000002,Trunks);INSERTINTOtable10VALUES(100000003,Susan);
  查看表中的数据,此时对应的rowid理论上是13:
  然后通过gdb命令把rowid改为最大值248,此时已超过dictsys。rowid最大值:gdbp2068expdictsysrowid281474976710656batch
  命令执行结果:
  再向表中插入三条数据:INSERTINTOtable10VALUES(100000004,King);INSERTINTOtable10VALUES(100000005,Queen);INSERTINTOtable10VALUES(100000006,Jack);
  查看表中的全部数据,可以看到第一次插入的三条数据中,有两条数据被覆盖了:
  为什么会出现数据覆盖的情况呢,我们对这一结果进行分析。首先,在第一次插入数据前rowid为1,插入的三条数据对应的rowid为1、2、3。如下图所示:
  当手动设置rowid超过最大值后,下一次插入数据时,插入的rowid重新从0开始,因此第二次插入的三条数据的rowid应该为0、1、2。这时准备被插入的数据如下所示:
  当出现相同rowid的情况下,新插入的数据会根据rowid覆盖掉原有的数据,过程如图所示:
  所以当表中的主键或唯一索引不满足我们前面提到的要求时,innoDB使用的隐式的rowid是存在一定风险的,虽然说248这个值很大,但还是有可能被用尽的,当rowid用尽后,之前的记录就会被覆盖。从这一角度也可以提醒大家,在建表时一定要创建主键,否则就有可能发生数据的覆盖。

今天超过80的仓库没有任何自动化世界已经开始进入了数字化和自动化的时代,自动化技术在社会、生活、经济、文化、医疗和媒体等领域的应用不断地扩大且成效显著。而作为制造业大军中数量和经济总量都庞大的中小型企业,数字……汽车人工智能与七个月的孩子谁更聪明?文丨来咖智库7个月大以后,多数孩子都已经学会了移出视线的物体仍然存在。把玩具放在毯子下面,孩子会知道玩具还在那里,并且可以伸手把它从毯子下面取回来。这种对于物体永久性的理……数字货币高富帅惨遭抛弃,价格几乎腰斩,发生了什么除了买彩票外,有没有可能一夜暴富,答案当然是有的;2009年数字货币比特币刚诞生时,价格还不足1美分,你花10元钱就可以买差不多近500个比特币,如果放到今年的4月份,那么你已……高通已抢占无人机制高点下一个科技制高点是什么?有人说是5G通讯。但我今天要说的是,5G通讯是一个宽泛化的概念,真正的下一个科技制高点是由5G通讯引发出来的科技实体行业。在这样的科技……红灯收音机和瓷介微调网上搜来的图片。94年上技校了,我仍有不起这类六管收音机。有个同学拿了图中这款收音机到学校听,我半开玩笑地说8元卖给我了,他还不肯,后来坏了,拿给他修家电的同学修去了,结果当然……抢购茅台,京东和天猫现状欢迎戳蓝字白酒圈儿关注。抢购的平台综合起来就那么多。可以点击这篇文章左下角的原文阅读,头部的文章,所有的平台都在里面,平台不会有什么太大的改变和增减,无非就是平台规……iOS15Beta5发布,HomePod无损音质也来了今日凌晨,苹果为开发者预览版用户推送了iOS15Beta5的更新。已经安装了iOS15测试版描述文件的用户可直接打开设置通用软件更新,直接在设备上OTA升级至最新的iOS15B……华为Mate50X大曝光,2K屏高刷新率后置四摄等,满满的诚无人不晓,华为手机是知名的手机厂商,以至于华为手机的一举一动都吸引着大家的目光。同时大家都知道华为是一个极致注重创新以及科技研发的手机厂商,因此华为手机为智能手机行业的发展做出……蔚来车主内讧超7800人反对被代表新京智库8月12日,蔚来车主林文钦驾驶蔚来ES8汽车在沈海高速涵江段发生交通事故不幸逝世。此次事件引发业内对自动驾驶技术安全性的讨论。蔚来车主林文钦车祸事件官方调查结果尚未公布,……为什么操作系统不能屏蔽底层的架构(arm,x86,mips)嗯,想了想,也就web浏览器有点接近这个意思了,不过运行权限就太低了你所说的屏蔽,就是上层做封装,但是封装以后带来的就是性能问题,比如安卓,如果你的代码全部用java写,……Redmi10海外正式发布,5000mAh电池康宁大猩猩玻璃近年来红米的市场表现不用多说,销量和口碑都很不错。小米能在短时间内取得全球销量第二,荣登欧洲市场销量第一的宝座,有一半都是子品牌红米的功劳。红米凭借着自身超高的性价比赢得了不少……科大讯飞消费者业务品牌全新升级AI助你超越所能8月24日,科大讯飞消费者业务发布全新品牌主张,发布全新业务宣言AI助你超越所能。基于展示科大讯飞围绕办公、学习、生活等场景,为大众用户提供易用、高效的AI产品和服务的宣传片《……
利物浦国家博物馆NationalMuseumsLiverpo利物浦国家博物馆(NationalMuseumsLiverpool)成立于1986年,其历史可追溯到1851年,由英格兰利物浦及其周边地区的七家博物馆和美术馆组成:利物浦博物馆……解决全家只有一台车的尴尬,6座顶配才是真奢享,有它看啥汉兰达中国汽车市场飞速发展,汽车的保有量也是越来越大,人均汽车占有量相比发达国家仍然不高,拥有一台车是我国大多数家庭共同的现状。因此对于很多用户来说,买一台车既要用来上下班代步通勤,……做高声价比的产品自然声公司目前的产品介绍和未来的规划(上)成立自然声公司,就是被逼的。没找到自己能喜欢的耳机,只好自己做,然后顺便卖卖养家糊口,到现在转眼快3年了。做一条自己喜欢的耳机,初心还是没变过,以后也会坚持!为什么有些耳……中国移动数字化新公司成立,和中国电信布局有何不同?2021年8月5日,中国移动通信集团有限公司在京举行了新公司成立揭牌仪式,中国移动通信集团有限公司董事长杨杰、总经理董昕等一行为新公司进行揭牌。新公司名为中移数智科技有限……大厂超廉价机械是什么体验?达尔优DK100图解前不久,达尔优一款DK100的老型号机械键盘在JD的特价95元,作为非悬浮式结构机械键盘在这个价位绝不常见,加上达尔优有8年的机械键盘历史,不像是营销或刷好评,可以一入。通过下……iPhoneSEPlus大曝光尺寸更大售价更便宜?最新消息显示:苹果的iPhoneSE3将会在2021年的4月份正式发布但是有很多人都表示iPhoneSE3有可能是iPhoneSE2的升级版本,在外观的设计上不会有变化,……为了环保自己购买的苹果20W快充头还算环保吗?充电器身为手机的充电设备,我们大家几乎每天都要用到。不过如今市面上的充电器厂家为了追求充电功率,因此都将手机的充电器做的特别大,而这对于一些经常需要出差的小伙伴来说则是非常的不……获得沃德十佳内饰沃德十佳发动机殊荣,英菲尼迪QX50竟然这么我们都知道英菲尼迪是日产旗下的高端品牌,当年的FX系列、G系列也深受消费者的欢迎,但时过境迁,在日产经历过一系列股权变更之后,英菲尼迪似乎也被忽视了,目前已经沦落成了一个比较小……AMD这是杀疯了?2021上半年攒机指南前几天(06。16)京东板U套装突然降到史低,在群里激起一阵抢购狂潮。上午出史低价格,下午出个更低的价格秒了上午的爆料。很多人退款了上午拍下的板U套装,买了下午新出……矿视界译文采用比特币作法币的萨尔瓦多现在怎样了?6月9日,萨尔瓦多宣布采用比特币作为其法定货币的消息在世界范围内引起了不小的轰动。比特币占领了它的第一个国家,这让比特币支持者们激动万分:这对比特币来说意义重大!比特币在现实世……张子枫亲自打call!OPPOReno6系列有何魔力?实际体6月1日上午10点,OPPO在官方微博上面晒出了OPPO光影STAR张子枫的相关信息,从微博上面的文案来看,OPPO似乎对自家的OPPOReno6系列产品的影像系统表现非常自信……销量不足万台,为何第一台5G手机销量如此惨淡?前几年中兴手机在国内市场还是有一定的市场份额,当年中华酷联可是国内手机品牌的4强,但最近几年在华为、小米、ov的冲击之下,中兴的手机市场份额越来越小,在4G时代,中兴在国内的市……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网