mysql插入数据会失败?为什么?

这篇具有很好参考价值的文章主要介绍了mysql插入数据会失败?为什么?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

牛肉丸裹上麻酱后,狠狠嘬一口,都要入嘴了。

产品经理突然发来消息。

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

心想着"关我x事,又不是我做的模块",放下手机。

不对,那老哥上礼拜刚离职了,想到这里,夹住毛肚的手微微颤抖

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

mysql插入数据会失败?为什么?

"如果用上表情符号的话,问题必现"

可以了,这下问题几乎直接定位了。

危,速归。

有经验的兄弟们很容易看出,这肯定是因为字符集的缘故。

复现问题

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

如果你有一张数据库表,建表sql就像下面一样。

mysql插入数据会失败?为什么?

建表sql语句

接下来如果你插入的数据是

mysql插入数据会失败?为什么?

insert成功case

能成功。一切正常。

但如果你插入的是

mysql插入数据会失败?为什么?

insert失败case

就会报错

Incorrect string value: '\xF0\x9F\x98\x81' for column 'name' at row 1

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

明明也是字符串,为什么字符串里含有emoji表情,插入就会报错呢?

我们从字符集编码这个话题开始聊起。

编码和字符集的关系

虽然我们平时可以在编辑器上输入各种中文英文字母,但这些都是给人读的,不是给计算机读的,其实计算机真正保存和传输数据都是以二进制0101的格式进行的。

那么就需要有一个规则,把中文和英文字母转化为二进制,比如"debug",计算机就需要把它转化为下图这样。

mysql插入数据会失败?为什么?

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多使用了一个字节。

mysql插入数据会失败?为什么?

unicode比ascii多使用一个字节

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

mysql插入数据会失败?为什么?

编码格式

来总结下。

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

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

mysql插入数据会失败?为什么?

字符和字符集的关系

mysql的字符集

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

mysql插入数据会失败?为什么?

数据库支持哪些字符集

上面这么多字符集,我们只需要关注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表情,它就不支持。

mysql插入数据会失败?为什么?

utf8mb3和utf8mb4的关系

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

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

这时候就需要用到collation了。

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

mysql插入数据会失败?为什么?

utf8mb4字符集比较规则

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

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

mysql插入数据会失败?为什么?

对比规则-大小写不敏感

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

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

mysql插入数据会失败?为什么?

对比规则-大小写敏感

那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 几乎没有劣势。

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

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

mysql插入数据会失败?为什么?

查看数据库表的字符集

再看报错原因

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

因为数据库表在建表的时候使用 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就行了,你会感谢我的。

 文章来源地址https://www.toymoban.com/news/detail-446109.html

 

到了这里,关于mysql插入数据会失败?为什么?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL Delete 表数据后,磁盘空间并未释放,为什么?

    有开发小哥咨询了一个问题,记录一下处理过程分享给有需要的朋友。 问题如下: MySQL数据库中有几张表增删比较频繁、数据变动剧烈且数据量大,导致数据增长过快,磁盘占用多。为了节约成本,定期进行数据备份,并通过delete删除表记录,但是执行delete操作后发现磁盘空

    2024年02月06日
    浏览(55)
  • MySQL为什么采用B+树作为索引底层数据结构?

            索引就像一本书的目录,通过索引可以快速找到我们想要找的内容。那么什么样的数据结构可以用来实现索引呢?我们可能会想到:二叉查找树,平衡搜索树,或者是B树等等一系列的数据结构,那么为什么MySQL最终选择了B+树作为索引的数据结构呢?         要想

    2024年02月16日
    浏览(46)
  • Facebook 用户量十分庞大,为什么还使用 MySQL 数据库?

    当谈到社交媒体巨头Facebook时,我们立刻想到的是其庞大的用户基础和每日海量的数据流。然而,您可能会惊讶地发现,尽管面对如此巨大的规模,Facebook 仍然选择使用 MySQL 数据库作为其核心的数据存储和管理系统。 为什么Facebook没有选择其他更强大或更高级的数据库系统?

    2024年02月04日
    浏览(49)
  • 阿里一面:MySQL 单表数据最大不要超过多少行?为什么?这样回答满分!

    来源:https://my.oschina.net/u/4090830/blog/5559454 作为在后端圈开车的多年老司机,是不是经常听到过,“mysql 单表最好不要超过 2000w”,“单表超过 2000w 就要考虑数据迁移了”,“你这个表数据都马上要到 2000w 了,难怪查询速度慢” 这些名言民语就和 “群里只讨论技术,不开车,

    2024年02月06日
    浏览(51)
  • 为什么SSL会握手失败?SSL握手失败原因及解决方案

    随着网络安全技术的发展,SSL证书作为网站数据安全的第一道防线,被越来越多的企业选择。SSL证书使用的是SSL协议,而SSL握手是SSL协议当中最重要的一部分。当部署SSL证书时,如果服务器和客户端之间无法建立安全连接,就会发生SSL握手失败的情况。本文将为您解释导致

    2024年02月21日
    浏览(50)
  • 为什么华为路由器修改MTU值失败

    MTU是MaximumTransmissionUnit的缩写,是网络上传送的最大数据包,大部分网络设备的MTU都是1500,MTU的单位是字节,如果本机的MTU比网关的MTU大,大的数据包就会被拆开来传送,这样会产生很多数据包碎片,增加丢包率,降低网络速度。 把本机的MTU设成比网关的MTU小或相同,就可以

    2024年02月05日
    浏览(43)
  • 为什么Apache Doris适合做大数据的复杂计算,MySQL不适合?

    经常有小伙伴发出这类直击灵魂的疑问: Q:“为什么Apache Doris适合做大数据的复杂计算,MySQL不适合?” A:“因为Apache Doris是OLAP,MySQL是OLTP啊!” Q:“SO?” A:“因为一个是AP场景的DB,一个是TP场景的DB啊!” Q:“SO?” … [emm] 要不先来简单概述下 OLAP和OLTP : OLAP (

    2024年01月19日
    浏览(52)
  • 幻兽帕鲁服务器为什么网络连接失败?

    幻兽帕鲁服务器网络连接失败可能有几个原因,例如防火墙没有配置,幻兽帕鲁专用端口8211未放通。如果是阿里云一键部署的幻兽帕鲁,可以打开安全组设置。如果是腾讯云一键部署的幻兽帕鲁,可以打开防火墙配置。   点击【添加规则】 协议选择【UDP】,端口输入【821

    2024年02月20日
    浏览(49)
  • 【哈希表】为什么哈希表的插入/删除/查找时间复杂度为O(1)

    在使用哈希表时,往往会出现哈希冲突,此时就会通过 链表/红黑树 的方法来解决冲突,此时引入 链表/红黑树 那么时间复杂度就不是严格的O(1)。 我们首先要明白N代表什么,N是指问题的规模大小。 在使用哈希表时,所有的数据个数为N,链表的长度肯定不是N,( 因为存在

    2024年03月21日
    浏览(52)
  • 为什么mac插入了u盘没反应 苹果mac插上usb后怎么找到

    U盘使用简单,便于携带,几乎每个mac用户都有一个u盘。使用新的u盘的时候,你有没有遇到过mac插入了u盘没反应的情况呢?如果你是初次接触Mac电脑,使用u盘可能会手足无措,因为Mac系统和Windows存在差异,本文就为大家介绍为什么mac插入了u盘没反应,苹果mac插上usb后怎么找

    2024年02月06日
    浏览(79)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包