android怎样判断插入数据是否成功_MySQL一个表的自增id用完了,背井大佬让我用这些姿势再往里插数据...

点击上方"码之初"关注,···选择"设为星标"

与精品技术文章不期而遇

在之前有篇文章中,和大家探讨了在MySOL数据库中,一个表的自增id用完,再插入数据有什么问题?评论处 @背井 公众号的大佬建议我另开一篇再说一下表的自增id在用完的情况下,用replace into、insert ignore以及insert... on duplicate会发生什么,当时不假思索就回复了安排,结果这一拖就快一个月了。

870f44220a4680c69ffc958e0195f274.png

海岳尚可倾,吐诺终不移。今天想到这件事,就立马先把标题写出来了,这样就能督促自己把这篇文章完成,你以为我是不想失信于尤慕大佬吗?是的,我不想!但同时,我更不想失信于自己!言归正传,开始我们今天的主题,当Mysql的一张表自增id用完了,此时再以各种姿势向表里插入数据会发生些什么呢?上一篇文章觉得说的不太好,有一些我想介绍的知识点没有讲到,所以通过这篇跟大家一起通过实践详细的探讨一番。

先创建一个简单的表,只包含一个自增字段id,像这样,勾选上自动递增和无符号

416601fbfc83deab74bc175f88fdeff5.png

此时我们可以看到右边的建表语句,注意一点,类型int(10)后面多了一个unsigned关键字,不知道你们是否都知道unsigned是什么意思,又是怎么出来的,如果不知道,就要好好看下去了,这是一个很重要的知识点。

unsigned

首先,勾选上左侧的无符号才会出现unsigned类型。那unsigned是什么意思呢?整型的每一种都有无符号(unsigned)和有符号(signed)两种类型,在默认情况下声明的整型变量都是有符号的类型(char有点特别)。由于在计算机中,整数是以补码形式存放的。根据最高位的不同,如果是1,有符号数的话就是负数;如果是无符号数,则都解释为正数。同时在相同位数的情况下,所能表达的整数范围变大。另外,unsigned若省略后一个关键字,大多数编译器都会认为是unsigned int。有没有不知所云或者不明觉厉,简单点解释就是,在mysql中创建表时,如果整型使用了unsigned类型,那么该数据项就永远是正整数,每种数值类型的名称和取值范围如下表所示:

949b13351c7f26bea3e91ab60bde603b.png

下面通过sql实例演示一下,我们先去掉勾选无符号,建表语句变成

ea40d33770cd98ea7cb97bf96b586b13.png

这时候已经没有unsigned了,我们向表里插入两条数据,一条正数一条负数:

INSERT INTO t VALUES (1);INSERT INTO t VALUES (-1);

结果显示插入成功

18c34999abbe0c4f59e9e10ed46d9e30.png

表里也有数据:

95af3edc37153b16fbecc4eed204825c.png

接下来我们修改表结构,勾选上无符号使用unsigned类型,像最初那样

5730aefd7fc4f40cc56c1dc7cb63ca48.png

这时候我们再向表里插入两条数据,一条正数一条负数:

INSERT INTO t VALUES (1);INSERT INTO t VALUES (-1);

看看执行结果:

c0c0f0b5d85a0958853c89722c054e93.png

发现-1不能插入表中,报错超出了范围值,因为使用了unsigned之后,int类型的值范围变成了0到4294967295(0 到232 - 1)4个字节,参考上面的表格:

55dd59e7af022da7db8ee8d78ac70c62.png

介绍了unsigned无符号类型之后,那大家应该都知道了使用了int unsigned类型字段数据理论上最大为4294967295,那么接下来我们就挑战极限,看看当一张表自增id用完了,此时再以各种姿势向表里插入数据会发生些什么?

姿势一:insert into

我们先直接暴力输出,在创建表的时候,直接将AUTO_INCREMENT的初始值声明为4294967295,sql如下:

CREATE TABLE `t` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

然后我们友好的向表中插一条数据:

INSERT INTO t VALUES (NULL);
你们猜一猜会发生什么,能插入成功吗?成功后表里长什么样子?先看一下执行结果:

ebb503bb0494c2b1b2eef2a2d1abb634.png

咦,成功了,什么情况,我们打开表看看:

c0c9d43e4e9eaf2b233fbdb0a3b4279d.png

这是什么鬼?我不是插入的null吗?

先解释第一个疑问,废话,当然能插进去了,因为AUTO_INCREMENT=4294967295是从这个开始,当然还能插进去,为什么插入null变成了4294967295,因为只有一个字段,插入的null又不是id的值,id是自增主键啊,现在明白了吧,有可能有人觉得我这两个问题好无聊,但是我真的见过有不少人不知道,不信你以后面试时可以随机问问。

高潮来了,我们这时候再插入一条数据呢,还能插进去吗?走起:

INSERT INTO t VALUES (NULL);

看结果,oh no,报主键冲突了:

e373800097fe73e09b49dbc348a3821e.png

这是为什么呢?上面我故意只截图了一半,我们看看第一次插入null成功,我们打开表后看看表的DDL语句:

987a5b8a08533c1fbc061582f0c777e2.png

可以看到,当再次插入时,使用的自增ID还是 4294967295,这时候就会报主键冲突的错误。其实4294967295这个数字已经可以满足大部分的应用场景了,如果你的服务会经常性的插入和删除数据的话,还是存在用完的风险,建议采用bigint unsigned,这个数字就大了。姿势二:replace insert如果表的自增id用完时,我们使用replace into继续插数据时,会发生什么呢?我们先直接执行:
REPLACE INTO t VALUES (NULL);

可以发现和之前报一样的错,都是主键冲突。

afc9730cc80ca22b5f9ca806518401c4.png

那么,是不是insert into和replace into这两条sql在自增id用完这种情况下,继续插入数据时发生了一样的遭遇呢?

我们下来看一下自增id未满的情况下,这两条sql是怎样执行的。

1、新建一张表,自增id就从1开始(默认也是从1)

DROP TABLE IF EXISTS t1;CREATE TABLE `t1` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`num` int(10) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

2、先使用insert into插入一条数据:

INSERT INTO t1 VALUES (1,1);

查看结果:

8426aea7b705102aac3e9e22ada864f4.png

看一下表结果:

72293ce7b7f596d7606652a7412ef0f7.png

3、再使用replace into:

REPLACE INTO t1 VALUES (1,1);

查看结果:

7e4bdb8de4133e04f24689542bd7ee13.png

看一下表结果:

72293ce7b7f596d7606652a7412ef0f7.png

4、再使用replace into:

REPLACE INTO t1 VALUES (1,2);

查看执行结果:

761b27f902c7be2f490535daf44aa320.png

再看一下表结果:

f514876a010ddd45f14183d85c89e209.png

看到这儿你有发现什么了吗?第一次insert into和replace into执行后受影响的行都是1行,第二次执行replace into后受影响的行变成了2行,为什么呢?这就是replace into和insert into的不同之处了。

划重点来了:

replace into 跟 insert 功能类似,不同点在于:replace into 首先尝试插入数据到表中,这时候:

  1. 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。

  2. 否则,直接插入新数据。

所以,最后一次执行replace into时受影响的行变成了2行。知道了replace into的执行原理后,我们回到自增id最大时,replace into报错,发生了什么呢?如果发现表中已经有了最大的id,会先删除这条数据,然后重新插入,但是此时虽然删除了此条数据,自增id依然是最大值,为什么呢?这就是自增主键没有持久化的bug。究其原因,在于自增主键的分配,是由InnoDB数据字典内部一个计数器来决定的,而该计数器只在内存中维护,并不会持久化到磁盘中,所以还会报主键冲突的错误。姿势三:insert ignore into

insert into ignore就比较简单了,我们直接运行sql看结果:

insert ignore into t VALUES (NULL);

结果显示:

6cfe818a39db220e0e91fb4f2b6c1bf7.png

可以看到受影响的行为0,这就是insert ignore 的作用:

  1. 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则跳过此查询,不对数据库作任何操作;

  2. 否则没有此行数据的话,直接插入新数据。

姿势四:insert ...on duplicate

老样子,我们先通过sql实例看看自增id最大时,使用insert... on duplicate key会发生什么,sql运行起来:

INSERT INTO t VALUES (NULL) ON DUPLICATE KEY UPDATE id =id+1;

查看运行结果:

2c0b06bdce8a6215902df3906423d976.png

依旧是主键冲突错误。

下面我们来简单分析一下INSERT ON DUPLICATE KEY UPDATE这条sql做了什么事。我们在日常业务开发中经常有这样一个场景,首先创建一条记录,然后插入到数据库;如果数据库已经存在同一主键的记录,则执行update操作,如果不存在,则执行insert操作,这个时候INSERT ON DUPLICATE KEY UPDATE就派上用场了。在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句,而要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新;如果插入的行数据与现有表中记录的唯一索引或者主键不重复,则执行新纪录插入操作。另外,ON DUPLICATE KEY UPDATE不能写where条件。以上就是当Mysql的一张表自增id用完了,此时再以各种姿势向表里插入数据会发生什么的一些实践探讨,同时也加了其他一些知识点的讲解,感谢尤慕大佬的建议,让我在漫漫路上多了一些求索的动力。

知识拓展

如果在创建表时没有显示声明主键,会怎么办呢?如果是这种情况,InnoDB会自动帮你创建一个不可见的、长度为6字节的row_id,而且InnoDB 维护了一个全局的 dictsys.row_id,所以未定义主键的表都共享该row_id,每次插入一条数据,都把全局row_id当成主键id,然后全局row_id加1,该全局row_id在代码实现上使用的是bigint unsigned类型,但实际上只给row_id留了6字节,这种设计就会存在一个问题:如果全局row_id一直涨,一直涨,直到2的48幂次-1时,这个时候再+1,row_id的低48位都为0,结果在插入新一行数据时,拿到的row_id就为0,存在主键冲突的可能性。所以,为了避免这种隐患,每个表都需要定一个主键。

最后,留下一个问题,大家知道int(0)和int(10)有什么区别吗?

59317539a598968e8818a814f6eb9718.png

ccc733297f3e984c7365e5645806d7ed.png

a7a126f1eafe26bd0772e9fbd76cc692.png

好文,点个在看吧d510ee61b706962c3bcdefc8dd3756d8.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/559555.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机硬件系统教具,计算机硬件系统 (2)

计算机硬件系统 (2) (3页)本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!9.9 积分计算机硬件系统克井一中杨致远教学目标:1、了解计算机的发展概况、特点以及种类2、理解计算机的工作原理3…

python 引入同一路径的类_Python入门 模块导入 import ...\from... import...

代码越来越多的时候,我们将代码写到一个.py 文件里,随着代码的增加,代码的维护越来越困难。如果将代码按照不同的功能拆分放到不同的.py文件中,每个.py文件就是一个模块。不同模块中的变量名可以相同,他们不会受影响。…

经典计算机实现量子逻辑门,量子计算机:对量子逻辑门的探讨

在分析了经典比特和量子比特的异同点之后,阐述了量子逻辑门的特点;然后具体介绍了几种常见的量子逻辑门:基本量子逻辑门,量子异或门,量子与门。最后又给出了更复杂的量子逻辑门的构建方法。维普资讯 http://doc.wendoc.com信息科学}J宋纳红侯丽敏科量子计算机&#…

命名空间中不存在名称_原木定制中不开裂的木材真的存在吗?

广大的读者朋友们大家好,之前壹信缅甸柚木高端全屋定制小编和大家讲解了为什么那么多人喜欢原木实木全屋定制护墙板,本文壹信小编将给大家讲讲原木整装中不开裂的木材真的存在吗。原木整装行业的从业人员都知道,最麻烦最让人担心的是木头的开…

电脑上交计算机作业怎么打开,上海交大计算机第一次作业-20210711011739.docx-原创力文档...

上海交大计算机第一次作业上海交大计算机第一次作业利用计算机进行数据处理的应用领域主要有事务处理、企业管理、______。a. 人工只能和办公自动化b. 办公自动化、信息资料检索 c. 信息资料检索和科学计算d. 事务处理和自动控制正确答案是:办公自动化、信息资料检索…

go 字符串替换_Go语言爱好者周刊:第 64 期 — goup 这个工具了解下

这里记录每周值得分享的 Go 语言相关内容,周日发布。本周刊开源(GitHub:polaris1119/golangweekly),欢迎投稿,推荐或自荐文章/软件/资源等,请提交 issue 。鉴于大部分人可能没法坚持把英文文章看…

北京师范大学新生入学计算机考试内容,北京师范大学

关于开展2020年本科新生奖学金评选及2019年本科新生奖学金复核工作的通知各相关部(院、系):为鼓励优秀高中毕业生报考我校,促进学生健康成长,不断提高学校人才培养质量,根据《北京师范大学(北京校区)本科新生奖学金评选方法(试行)…

opencore0.6.3_Ubuntu 18.04 源码编译安装 PHP 7.3

记录在Ubuntu 18.04下源码编译安装 PHP 7.3的过程步骤。0.下载PHP源代码首先需要从PHP官网下载PHP7.3.1的源代码,保存为php-7.3.1.tar.xz。http://cn2.php.net/distributions/php-7.3.1.tar.xz在上述文件保存的目录中打开终端,使用命令将其解压&#xff…

计算机 电工学简明教程,电工学简明教程复习要点

《电工学简明教程复习要点》由会员分享,可在线阅读,更多相关《电工学简明教程复习要点(88页珍藏版)》请在人人文库网上搜索。1、本章要求掌握1 .旁路电流法、叠加原理、达宾定理等电路的基本分析方法。 2 .了解实际电源的两种模型及其等效变换。 3 .了解…

photoshop案例_玩手机不如学PS!200集入门到精通Photoshop自学教程分享3

大家都知道Photoshop(PS)的功能非常的强大,它具有强大的绘图、校正图片及图像创作功能!人们可以利用它创作出具有原创性的作品。应用极为广泛,常应用于平面设计、网页设计、插画设计、界面设计、数码照片与图像的修复、…

计算机核心手稿,梁思成建筑手稿曝光:在没有计算机的年代,他的认真细致令人敬佩...

说起梁思成,人们首先就会想到他与林徽因之间的感情纠葛。在才女林徽因的身边,梁思成一度成为默默无闻的“绿叶”,在悄无声息地衬托他的爱人。而实际上,梁思成具有超高的建筑艺术水平和闪闪发光的建筑设计技艺。今天,我…

latex 符号_sympy: 符号运算-1

本文主要参考资料来自sympy的官网:Introduction - SymPy 1.4 documentation​docs.sympy.org一般,我们使用计算机软件进行数学计算,主要是数值计算,就算有变量,也是代入具体数值来算的,我们在初中到大学学到…

西浦与杭电计算机选哪个,四邮四电究竟谁强谁弱?哪三所大学报考更有性价比?...

四邮 北京邮电学院 南京邮电学院 西安邮电大学 重庆邮电学院 四电 西安电子科技大学 电子科技大学 桂林电子科技大学 杭州电子科技大学。总体来说:成电西电>北邮>杭电>南邮重邮≈桂电>西邮。实力基本和各校年经费成正比,成电>西电>北邮…

android 获取当前时间_js如何获取当前时间并显示

js可以通过Date对象获取当前日期和时间,使用Date()获取系统当前时间,在使用getFullYear()、getMonth()、getDate() 、getHours()等方法获取特定格式的时间,在使用innerHTM方法显示。web前端学习:打造全网web前端全栈资料库&#x…

css居中的几种方法_CSS布局中的水平居中的方法

在我们做网站的过程中,怎么都逃不掉居中这个话题,各种花里胡哨的,可能只需要掌握两三个就可以完成一个网页的布局了。今天就来介绍下水平居中有哪些方法。第一种,设置当前元素水平居中,元素为block时要让p元素水平居中…

如何唤醒计算机,待机后如何唤醒计算机?介绍睡眠待机的优势

当我们将鼠标拖到习惯的位置时,我们会发现计算机实际上包括三个选项:关机,重新启动和睡眠。睡眠意味着您暂时不需要使用计算机,但是在需要时,界面可以保持不变。但是很不知道睡觉后怎么醒?如果您无法成功唤…

apollo 配置中心_配置中心——Apollo小记

一、什么是配置配置是程序运行时,动态调整行为的能力。配置有以下属性:配置是独立于程序的只读变量同一份程序在不同的配置下才会有不同的行为,而且配置对于程序来说是只读的,所以程序可以通过读取配置来改变自己的行为&#xff0…

云南计算机专修学校附中,昆明高中哪家强? 师附中和昆一中高考尖子生最多...

原标题:昆明高中哪家强? 师附中和昆一中高考尖子生最多云南网讯(记者 念新洪)昆明高中哪家强?来从11月16日公示的“昆明市2015年高中教育质量考核结果”中找答案吧!据悉,根据年初签订的责任书和目标考核规定&#xff0…

python在线编辑器import_maya_关于脚本编辑器导入python模块

import sys for p in sys.path: print p rigDir C:\Users\lenovo\Documents\maya\scripts\python\rigLib if not rigDir in sys.path: sys.path.append( rigDir ) from rigLib.base.control import * ArmCtl rigLib.base.control.Control(prefix 1_arm) 问题与解决方法 # Er…

css button 四种状态,css中按钮的四种状态

css中按钮有四种状态普通状态hover 鼠标悬停状态active 点击状态focus 取得焦点状态.btn:focus{outline:0;} 可以去除按钮或a标签点击后的蓝色边框下面的例子中.btn1用focus按钮会按下,不弹起.btn2用active按钮点击按下,会弹起html:Save Sett…