zoukankan      html  css  js  c++  java
  • 一个emoji引发的一条血案:mysql存储emoji表情字符时报错解决

    以下是我插入一条带表情的数据到mysql后出现错误

    2019-03-04 14:24:40,462 ERROR 2807 [-/139.199.27.244/-/2ms POST /api/activityAdd] nodejs.ER_TRUNCATED_WRONG_VALUE_FOR_FIELDError: ER_TRUNCATED_WRONG_VALUE_FOR_FIELD: Incorrect string value: 'xF0x9Fx98x82' for column 'content' at row 1
    

    报错原因:

    mysql的utf8编码的一个字符最多3个字节,但是一个emoji表情为4个字节,所以utf8不支持存储emoji表情。但是utf8的超集utf8mb4一个字符最多能有4字节,所以能支持emoji表情的存储

    解决办法:

    解决方式有2种:
    1、在前端通过js对字符串进行编码然后再保存到数据库中,取出来时再对内容进行解码

    2、通过修改数据库字符编码utf8mb4

    第一种解决方式是使用js提供的方法escape和unescape来对内容进行编解码,但是问题也很明显,就是在每个需要显示和保存的地方我们都需要使用escape和unescape去做处理,这无疑增加了工作量。还有就是我们使用escape编码之后的内容长度特别长,在数据库表字段上需要设计很大的长度,对数据库性能影响也比较大

    综合考虑排除掉这种方式,使用第二种方式去解决

    解决过程:

    1、linux中修改my.cnf配置文件(默认路径/etc/my.cnf)

    关于my.cnf配置文件参数说明
    https://baijiahao.baidu.com/s?id=1608929505838938265&wfr=spider&for=pc

    修改之前先查看当前数据库字符编码

    SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
    
    character_set_client	utf8mb4
    character_set_connection	utf8mb4
    character_set_database	utf8
    character_set_filesystem	binary
    character_set_results	utf8mb4
    character_set_server	latin1
    character_set_system	utf8
    character_sets_dir	/usr/local/mysql/share/charsets/
    collation_connection	utf8mb4_general_ci
    collation_database	utf8_bin
    collation_server	latin1_swedish_ci
    

    可以看到目前我们数据库编码使用的是utf8

    关于collation_connection 、collation_database 、collation_server关系

    系统变量 描述
    character_set_client (客户端来源数据使用的字符集)

    character_set_connection (连接层字符集)

    character_set_database (当前选中数据库的默认字符集)

    character_set_results (查询结果字符集)

    character_set_server (默认的内部操作字符集)

    之后,我们在my.cnf中添加如下配置

    [client] 
    default-character-set = utf8mb4 
    [mysql] 
    default-character-set = utf8mb4 
    
    [mysqld] 
    character-set-client-handshake = FALSE 
    character-set-server = utf8mb4 
    collation-server = utf8mb4_unicode_ci 
    init_connect='SET NAMES utf8mb4'
    

    然后重启mysql

    service mysqld restart
    

    将数据库和已经建好的表也转换成utf8mb4

    以上方式更改编码对于已有的库和表是不产生影响的,需要我们单独进行转换。

    更改数据库编码:ALTER DATABASE caitu99 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    
    更改表编码:ALTER TABLE TABLE_NAME CONVERT TO CHARACTER SET utf8mb4 COLLATEutf8mb4_general_ci; 
    如有必要,还可以更改列的编码
    

    修改后需要再重启mysql服务

    插入一条表情数据测试

    INSERT INTO tb_test (id,name) VALUES (55, x'F09F9A8A');
    

    参考阅读

    https://blog.csdn.net/asahinokawa/article/details/85255732
    https://www.cnblogs.com/zhangwufei/p/7017325.html
    https://dba.stackexchange.com/questions/89355/unable-to-insert-utf8mb4-characters-in-mysql-5-6
    https://blog.csdn.net/eagle89/article/details/82148751
    https://www.cnblogs.com/chyingp/p/mysql-character-set-collation.html

  • 相关阅读:
    决策树算法之ID3
    MSE与MAE的区别与选择
    (九)关键变量发掘技术
    (八)数据集切割
    (七)数据精简之(数据值精简和字段的精简)
    (六)数据精简之(数据记录精简)
    (五)数据编码是干什么
    (四)数据清洗主要工作
    pip-window安装
    CMDB学习之六 --客户端请求测试,服务端api优化
  • 原文地址:https://www.cnblogs.com/fozero/p/10472522.html
Copyright © 2011-2022 走看看