专业编程基础技术教程

网站首页 > 基础教程 正文

MySQL:字符集问题 mysql字符集设置命令

ccvgpt 2024-10-12 13:33:12 基础教程 9 ℃

事件起源与分析

收到客户发来的请求报文,入库后发现有些字符不能正常显示。查看日志发现insert操作中,字段内容没有问题。于是开始排查:

首先我们先来查看当前数据库的字符集

MySQL:字符集问题 mysql字符集设置命令

show variables like ‘character_set_%’

结果如下

Variable_name         Value
character_set_client utf8mb4
character_set_connection utf8mb4
character_set_results utf8mb4
character_set_server utf8mb4
character_set_database utf8mb4
character_set_system utf8
character_sets_dir C:\Program Files\MySQL\MySQL Server 8.0\share\charsets\
character_set_filesystem binary

各个字段具体意义如下:

  • character_set_client
    主要用来设置客户端使用的字符集。通俗的讲就是mysql把客户端传递过来的数据都当成是utf8mb4
  • character_set_connection
    主要用来设置连接数据库时的字符集,如果程序中没有指明连接数据库使用的字符集类型则按照这个字符集设置。
  • character_set_database
    主要用来设置默认创建数据库的编码格式,如果在创建数据库时没有设置编码格式,就按照这个格式设置。
  • character_set_filesystem
    文件系统的编码格式,把操作系统上的文件名转化成此字符集,即把 character_set_client转换character_set_filesystem, 默认binary是不做任何转换的。
  • character_set_results
    数据库给客户端返回时使用的编码格式,如果没有指明,使用服务器默认的编码格式。通俗的讲就是mysql发送个客户端的数据是utf8mb4的
  • character_set_server
    服务器安装时指定的默认编码格式,这个变量建议由系统自己管理,不要人为定义。
  • character_set_system
    数据库系统使用的编码格式,这个值一直是utf8,不需要设置,它是为存储系统元数据的编码格式。
  • character_sets_dir
    这个变量是字符集安装的目录。


通过以上信息进行分析,我们可以推断

  • 插入语句没有问题
  • 后台字符集为utf8mb4,支持生僻字

剩下只能是程序连接数据库时是否设置了什么,进一步排查代码发现MySQL建立连接之后执行了如下语句,原因找到了。

mysql_set_character_set(mysql, "utf8");

解决方法

mysql在C/C++中调用api设置连接mysql的编码方式有以下几种方法:

1. mysqli_set_charset

ret = mysql_set_character_set(mysql, "utf8mb4");
ret = mysql_set_character_set(mysql, "utf8mb4");

说明:

推荐使用的设置方法,与mysql的连接断开自动重连后仍能保持设置的编码格式,并且影响mysql_real_escape_string函数功能,使mysql_real_escape_string函数使用设置的编码格式转义字符串。

2. 执行sql语句:SET NAMES

ret = mysql_real_query(mysql, "SET NAMES UTF8MB4;",
(unsigned long) strlen ("SET NAMES UTF8MB4;"));
ret = mysql_real_query(mysql, "SET NAMES UTF8MB4;",
(unsigned long) strlen ("SET NAMES UTF8MB4;"));

说明:

使用sql语句执行,只能影响当前与数据库的连接,断开自动重连后编码格式会重置为默认的配置。

3. 设置MYSQL_SET_CHARSET_NAME属性

ret = mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4");
ret = mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4");

说明:

跟mysql_set_character_set类似,断开自动重连后仍能保持设置的编码格式,只是不会影响到mysql_real_escape_string函数。 需要特别说明的是只有在调用mysql_real_connect连接数据库之前修改该属性才会生效。

Tags:

最近发表
标签列表