MySQL编码探究

前言

时位于 2002 年,MySQL4.1 版本开始支持 UTF-8 编码,由于当时采用RFC 2279规定该编码使用 1~6 字节存储单个字符,MySQL 开发者在同年 9月对源码进行了修改,将 UTF-8 编码从最大 6字节变更为 3字节,也就有了现在的UTF8MB3。 我们都知道,UTF8MB3是无法存储 SMP(Supplementary Multi-lingual Plane)字符的,而 MySQL 后来基于RFC 3629 标准新增了UTF8MB4。这时候我们只需要将表(Table)和字段(Column)的编码类型设置为UTF8MB4即可。 但在事实上,建立 MySQL 连接时通过SET NAMES指定的编码类型同样会影响到 SMP 字符的传输。 本文主要对连接 MySQL 时候编码指定的逻辑进行分析

Connector 源码分析

以下基于mysql-connector-java依赖包的5.1.46以及5.1.47版本,其他版本在实现上也许会有不同。

上述问题的原因是因为当 MySQL 实例化一个 Connector 时,会通过一个 Set 集合UTF8MB4_INDEXES是否包含变量serverCharsetIndex来得到一个 Boolean 变量useutf8mb4,后续会执行SET NAMES时会通过useutf8mb4变量判断是使用UTF8MB4还是UTF8。接下来我们跟着代码看看这些变量是如何被赋值的。

mysql-connector-java 5.1.46

  • CharsetMapping

    CharsetMapping 类被初始化时,它内部的静态代码块就会被执行

    public static final int MAP_SIZE = 2048;
    ......
    // 保存 MySQL 编码以及排序规则
    Collation[] collation = new Collation[MAP_SIZE];
    ......
    collation[33] = new Collation(33, "utf8_general_ci", 1, MYSQL_CHARSET_NAME_utf8);
    ......
    collation[45] = new Collation(45, "utf8mb4_general_ci", 1, MYSQL_CHARSET_NAME_utf8mb4);
    collation[46] = new Collation(46, "utf8mb4_bin", 0, MYSQL_CHARSET_NAME_utf8mb4);
    ......
    collation[255] = new Collation(255, "utf8mb4_0900_ai_ci", 0, "utf8mb4");
    ......
    Set<Integer> tempUTF8MB4Indexes = new HashSet<Integer>();
    Collation notUsedCollation = new Collation(0, COLLATION_NOT_DEFINED, 0, NOT_USED);
    for (int i = 1; i < MAP_SIZE; i++) {
      Collation coll = collation[i] != null ? collation[i] : notUsedCollation;
      COLLATION_INDEX_TO_COLLATION_NAM
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值