• 自动秒收录
  • 软件:1973
  • 资讯:56936|
  • 收录网站:211313|

IT精英团

mysql会无法插入数据?为什么?

mysql会无法插入数据?为什么?

浏览次数:
评论次数:
编辑: 乐咏
信息来源: ITPUB
更新日期: 2022-06-23 20:56:45
摘要

以下文章来源于公众号-小白debug,作者小白那天,我还在外面吃成都六姐的冒菜。牛肉丸裹上麻酱后,狠狠嘬一口,都要入嘴了。产品经理突然发来消息。"线上有些用户不能注册了"心想着"关我x事,又不是我做的

  • 正文开始
  • 相关阅读
  • 推荐作品

以下文章来自微信官方账号——小白调试,作者小白。

那天,我还在吃成都六姐的冒菜。

牛肉丸裹上芝麻酱后,咬起来很用力,几乎就在嘴里了。

产品经理突然发来消息。

"线上有些用户不能注册了"

想着‘这是我的事,不是我的模块’,放下电话。

不,那个兄弟上周刚走。想到这里,他抓住了微微颤抖.毛肚的手

继续送对面:"还有些用户不能改名"

如果使用表情符号,就会出现问题

好了,现在问题差不多直接定位了。

身处险境,速归。

有经验的兄弟很容易看出,这一定是因为字符集.

复现问题

我们来简单重现一下这个问题。

如果您有一个数据库表,构建表sql如下所示。

构建一个表sql语句。接下来,如果您插入的数据是

成功插入案例能成功.一切正常。

但是如果你插入

如果插入失败,情况将是报错.

对于列“name”atrow1,字符串值:“\ xF0 \ x9F \ x98 \ x81”不正确

区别在于后者多了个emoji表情。

明明也是一串。为什么字符串包含emoji表情,所以在插入时会出错?

先说字符集编码.的话题

编码和字符集的关系

虽然我们平时可以把各种中英文字母输入编辑器,但是这些是给人看的,不是给电脑看的。事实上,计算机实际上是以二进制0101的格式存储和传输数据的。

然后需要有一个把中英文字母转换成二进制的规则,比如‘debug’,计算机需要转换成下图。

3CA379568AF5C5FD.jpg" width="1200" src="https://image.z.itpub.net/zitpub.net/JPG/2022-06-23/789635EA0BBA75103CA379568AF5C5FD.jpg">

debug的编码

其中d对应十六进制下的64,它可以转换为01二进制的格式。

于是字母和数字就这样一一对应起来了,这就是ASCII编码格式。

它用一个字节,也就是8位来标识字符,基础符号有128个,扩展符号也是128个。

也就只能表示下英文字母和数字

这哪里够用。

塞牙缝都不够。

于是为了标识中文,出现了GB2312的编码格式。为了标识希腊语,出现了greek编码格式,为了标识俄语,整了cp866编码格式。

这百花齐放的场面,显然不是一个爱写if else的程序员想看到的。

为了统一它们,于是出现了Unicode编码格式,它用了2~4个字节来表示字符,这样理论上所有符号都能被收录进去,并且它还完全兼容ASCII的编码,也就是说,同样是字母d,在ASCII用64表示,在Unicode里还是用64来表示。

不同的地方是ASCII编码用1个字节来表示,而Unicode用则两个字节来表示。

比如下图,同样都是字母d,unicode比ascii多使用了一个字节。

unicode比ascii多使用一个字节

我们可以注意到,上面的unicode编码,放在前面的都是0,其实用不上,但还占了个字节,有点浪费,完全能隐藏掉。如果我们能做到该隐藏时隐藏,这样就能省下不少空间,按这个思路,就是就有了UTF-8编码

编码格式

来总结下。

按照一定规则把符号和二进制码对应起来,这就是编码。而把n多这种已经编码的字符聚在一起,就是我们常说的字符集

比如utf-8字符集就是所有utf-8编码格式的字符的合集。

字符和字符集的关系


mysql的字符集

想看下mysql支持哪些字符集。可以执行 show charset;

数据库支持哪些字符集

上面这么多字符集,我们只需要关注utf8和utf8mb4就够了。


utf8和utf8mb4的区别

上面提到utf-8是在unicode的基础上做的优化,既然unicode有办法表示所有字符,那utf-8也一样可以表示所有字符,为了避免混淆,我在后面叫它大utf8

而从上面mysql支持的字符集的图里,我们看到了utf8和utf8mb4。

先说utf8mb4编码,mb4就是most bytes 4的意思,从上图最右边的Maxlen可以看到,它最大支持用4个字节来表示字符,它几乎可以用来表示目前已知的所有的字符。

再说mysql字符集里的utf8,它是数据库的默认字符集。但注意,此utf8非彼utf8,我们叫它小utf8字符集。为什么这么说,因为从Maxlen可以看出,它最多支持用3个字节去表示字符,按utf8mb4的命名方式,准确点应该叫它utf8mb3

不好意思,有被严谨到的兄弟们,评论区扣个"严谨"。

它就像是阉割版的utf8mb4,只支持部分字符。比如emoji表情,它就不支持。

utf8mb3和utf8mb4的关系


而mysql支持的字符集里,第三列,collation,它是指字符集的比较规则

比如,"debug"和"Debug"是同一个单词,但它们大小写不同,该不该判为同一个单词呢。

这时候就需要用到collation了。

通过SHOW COLLATION WHERE Charset = 'utf8mb4';可以查看到utf8mb4下支持什么比较规则。

utf8mb4字符集比较规则

如果collation = utf8mb4_general_ci,是指使用utf8mb4字符集的前提下,挨个字符进行比较general),并且不区分大小写(_ci,case insensitice)。

这种情况下,"debug"和"Debug"是同一个单词

对比规则-大小写不敏感

如果改成collation=utf8mb4_bin,就是指挨个比较二进制位大小

于是"debug"和"Debug"就不是同一个单词。

对比规则-大小写敏感


那utf8mb4对比utf8mb3有什么劣势吗?

我们知道数据库表里,字段类型如果是char(2)的话,里面的2是指字符个数,也就是说不管这张表用的是什么编码的字符集,都能放上2个字符。

而char又是固定长度,为了能放下2个utf8mb4的字符,char会默认保留2*4(maxlen=4)= 8个字节的空间。

如果是utf8mb3,则会默认保留 2 * 3 (maxlen=3) = 6个字节的空间。也就是说,在这种情况下,utf8mb4会比utf8mb3多使用一些空间。

但这真的无关紧要,如果我不用char,用varchar就好了,varchar不是固定长度,也就没有上面这些麻烦事了。

所以我个人认为,utf8mb4比起 utf8mb3 几乎没有劣势。


如何查看数据库表的字符集

如果我们不知道自己的表是用的哪种字符集,可以通过下面的方式进行查看。

查看数据库表的字符集


再看报错原因

到这里,我们回到文章开头的问题。

因为数据库表在建表的时候使用 DEFAULT CHARSET=utf8, 相当于指定了utf8mb3字符集格式。

而在执行insert数据的时候,又不讲武德,加入了emoji表情这种utf8mb4才能支持的字符,mysql识别到这是utf8mb3不支持的字符,于是忍痛报错。

要修复也很简单,执行下面的sql语句,就可以把数据库表的字符集改成utf8mb4

ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

答应我,以后建表,我们都无脑选utf8mb4。

选utf8除了在char字段场景下会比utf8mb4稍微省一点空间外,几乎没任何好处。

这点空间省下来了能提高你的绩效吗?不能。

但如果因此炸雷了,那你号就没了。


总结

  • ASCII编码支持数字和字母。大佬们为了支持中文引入了GB2312编码格式,其他国家的大佬们为了支持更多语言和符号,也引入了相应的编码格式。为了统一这些各种编码格式,大佬们又引入了unicode编码格式,而utf-8则在unicode的基础上做了优化,压缩了空间。

  • mysql默认的utf8字符集,其实只是utf8mb3,并不完整,当插入emoji表情等特殊字符时,会报错,导致插入、更新数据失败。改成utf8mb4就好了,它能支持更多字符。

  • mysql建表时如果不知道该选什么字符集,无脑选utf8mb4就行了,你会感谢我的。

Linux系统的故障排除与修复技巧
« 上一篇 2022-06-23
  • Linux系统的故障排除与修复技巧
    0阅读 0条评论 个赞
    我发现Linux系统在启动过程中会出现一些故障,导致系统无法正常启动,我在这里写了几个应用单用户模式、GRUB命令操作、Linux救援模式的故障修复案例帮助大家了解此类问题的解决。(一)单用户模式Li……
  • python异常处理10分钟
    0阅读 0条评论 个赞
    异常处理:捕获异常,简单的捕获异常语法,在程序开发时,可以尝试加如try来捕获异常try:尝试执行的代码except:出现错误的处理try尝试下方填写要尝试的密码,不确定能不能够正常执……
  • 知道雷迪斯关系数据库这些细节,可以少踩很多坑
    0阅读 0条评论 个赞
    在使用Redis的过程中,你是否遇到过下面这些问题:开启RDB落盘,业务频繁出现请求超时。除了save和bgsave命令,还有哪些操作会触发RDB落盘?执行了flushall,发……
  • 大厂中的技术专家:建筑设计中的常见思维模式
    0阅读 0条评论 个赞
    上周我写的一篇文章《关于技术能力的思考和总结》引起了大家的关注,好多读者的评论“以写代想、以想促真、以讲验真”,大家的感受很深刻,基于上次的文章,这篇文章我其实更想跟大家聊聊一些常用的思考方法,思考问……
  • 在线K8s群集性能评估 基本服务部署调整
    0阅读 0条评论 个赞
    对于非结构化的数据存储系统来说,LIST操作通常都是非常重量级的,不仅占用大量的磁盘IO、网络带宽和CPU,而且会影响同时间段的其他请求(尤其是响应延迟要求极高的选主请求),是集群稳定性的一……
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
  • 你还不明白分布式会话怎么解决?就看这个吧!
    23阅读 0条评论 个赞
    平常做的项目都是在一台应用系统,并且所有的操作都在一台Tomcat服务器上,并不会引发Session共享的问题,所以并不会对我们的系统产生影响,但是当我们部署多个微服务的时候,再搭配Nginx进行负载……
  • Arch Linux超越Ubuntu成功登顶
    10阅读 0条评论 个赞
    Steam5月调查结果发布啦,本月Linux平台的用户百分比基础略有下降,而且最受欢迎的Linux发行版从UbuntuLTS转向了ArchLinux。Steam5月份的调查结……
  • 如何在Mac上愉快地使用Docker
    0阅读 0条评论 个赞
    一、目标任务首先要明确的是,作为了一个每天在LinuxServer上rm-rf的人来说,如果想在Mac上使用Docker,最舒服的也是兼容所有dockercli命令行操作……
  • 如何构建自己的可引导Linux Live CD
    2阅读 0条评论 个赞
    使用第三方工具或官方Linux操作系统,在Linux中创建DIY可启动LiveCD很容易。需要帮忙?按照以下步骤在几分钟内创建LinuxLiveCD。LiveCD(或“liv……
  • 当字节跳动向美国出口中国996.
    0阅读 0条评论 个赞
    作者|GeorgiaWells/YoreeKoh/SalvadorRodriguez来源|WSJ在荣克离职时发布的一份内部备忘录中,他说,“TikTok对待员工的方式与TikTok平台代表的……
  • 如何保证MySQL和Redis的数据一致性?
    1阅读 0条评论 个赞
    以下文章来源于公众号-楼仔,作者楼仔我直接先抛一下结论:在满足实时性的条件下,不存在两者完全保存一致的方案,只有最终一致性方案。根据网上的众多解决方案,总结出6种,直接看目录:不好的方案1.先……
  • “由于一个Linux sudo命令 我的Twitter账户被封了!”
    1阅读 0条评论 个赞
    整理|苏宓出品|CSDN(ID:CSDNnews)一个月前,马斯克想要用440亿美元收购国外的社交平台巨头Twitter,旨在改变Twitter的审核政策,实现真正的言论自由。然而,这……
  • 20个实用的以打字打的文件单行代码汇总
    0阅读 0条评论 个赞
    来源|https://blog.bitsrc.io/another-10-quick-typescript-one-liners-9f41713c158a在今天的文章中,我将与你分享20有用的T……
  • 为实战构建数据仓库指标体系!
    0阅读 0条评论 个赞
    作者:曹雷来源:滴滴技术01指标体系1.痛点分析主要从业务、技术、产品三个视角来看:业务视角业务分析场景指标、维度不明确;频繁的需求变更和反复迭代,数据报表臃肿,数据参差不齐;用户分析具体业务问题找……
  • 什么样的数据有资格成为资产?
    0阅读 0条评论 个赞
    以下文章来源于公众号-大鱼的数据人生,作者讨厌的大鱼先生维克托·迈尔·舍恩伯格在《大数据时代》中曾经提到:“虽然数据还没有被列入企业的资产负债表,但这只是一个时间问题”。现在很多企业开始提数据是资产甚……
  • 老工程师总结的10条经验 太有益了~
    1阅读 0条评论 个赞
    正文到现在,我已经做了超过21年开发,可以说,我生命中超过一半的时间都在编程,那既是我的职业,也成了我的习惯。下面是我在开发过程中学到的10条最有价值的经验。1你永远不可能什么都知道尤其是在开……
  • 嵌入式系统登录的简单方法
    3阅读 0条评论 个赞
    来源|我姓梁很多场景都需要记录日志,在嵌入式系统中,特别是单片机这种存储资源有限的环境下,就需要一种轻量级的存储方法。系统日志在嵌入式设备应用场景中,系统日志时常可以监控设备软件的运行状态,及时记录……
  • 云原生后台运维改造的SRE实践
    0阅读 0条评论 个赞
    一、前言上一篇文章《云原生背景下的运维价值思考与实践(上)》重点介绍了云原生背景下运维转型的思考,围绕着整个DevOps交付链,贴近业务不断输出运维的能力与价值。这篇内容我想谈谈DevOps的……
  • 拯救你生命的5个python技巧
    0阅读 0条评论 个赞
    Python是一种强大且易上手的语言,语法简洁优雅,不像Java那么繁琐废话,并且有一些特殊的函数或语法可以让代码变得更加简短精悍。根据笔者经验,下面介绍常用的5个python小技巧:字符串操作列表推……
  • 运维入坑必看:Kubernetes平台架构解读
    1阅读 0条评论 个赞
    Kubernetes是一个开源容器编排平台,管理大规模分布式容器化软件应用,是云计算发展演进的一次彻底革命性的突破。Kubernetes是谷歌的第三代容器管理系统,是Borg独特的控制器和Omega灵……
  • 如何通过缓存提高系统性能
    1阅读 0条评论 个赞
    缓存在系统中最消耗性能的地方就是对数据库的访问了,一般来说,增、删、改操作不会出现什么性能问题,除非索引太多,并且数据量有十分庞大的情况下,这三个操作才会导致性能问题。一般可以限制单表索引的数量来提升……
  • 知道雷迪斯关系数据库这些细节,可以少踩很多坑
    0阅读 0条评论 个赞
    在使用Redis的过程中,你是否遇到过下面这些问题:开启RDB落盘,业务频繁出现请求超时。除了save和bgsave命令,还有哪些操作会触发RDB落盘?执行了flushall,发……
  • 分享:Linux的6个实际应用
    0阅读 0条评论 个赞
    众所周知,Linux为全球数百万台服务器和台式机提供支持。但是这个开源操作系统还有其他应用吗?如果您在桌面上使用Linux,您可能想知道您正在使用的操作系统有哪些实际用途。幸运的是,今天有很多L……
  • 深度知识的六个维度:如何让人工智能真正理解世界?
    1阅读 0条评论 个赞
    智能的真正标志不是知识,而是想象力。作者|GadiSinger编译|王玥编辑|陈彩娴什么知识让我们变得聪明?我们用来理解世界、解释新体验和做出深思熟虑的选择的认知结构是什么?定义一个阐明……
  • 还记得发现redis使用不当导致的应用卡顿bug的过程吗?
    1阅读 0条评论 个赞
    首先说下问题现象:内网sandbox环境API持续1周出现应用卡死,所有api无响应现象。刚开始当测试抱怨环境响应慢的时候,我们重启一下应用,应用恢复正常,于是没做处理。但是后来问题出现频率越来越频……
最近发布资讯
更多