MySQL高级讲座篇之:`utf8mb4`编码与Emoji:Unicode支持在MySQL中的演进与实践。

各位观众老爷们,大家好!我是今天的主讲人,咱今天就来唠唠MySQL里头的 utf8mb4,还有那些个让人又爱又恨的 Emoji。

咱们先来热热身,想想当年,MySQL 对 Unicode 的支持,那可真是…一言难尽。

一、MySQL与Unicode的“爱恨情仇”

话说早些年,MySQL 还是个小年轻的时候,对 Unicode 的支持那叫一个“半吊子”。它有个叫 utf8 的编码,你以为它支持所有 Unicode 字符?Too young, too simple! utf8 实际上只支持 BMP (Basic Multilingual Plane) 里的字符,也就是 Unicode 里的前 65535 个字符。 这就导致一些比较“潮”的字符,比如 Emoji、一些生僻字等等,utf8 就歇菜了。

你想想,你用 utf8 建个表,想往里存个 Emoji,结果要么报错,要么存进去的是一堆乱码,是不是想砸电脑?

所以,MySQL 就得想办法解决这个问题,于是乎,utf8mb4 就应运而生了。

二、utf8mb4:真·Unicode 大哥

utf8mb4 才是真正的 Unicode 完全体!它支持所有 Unicode 字符,包括那些 BMP 之外的“妖艳贱货”。 也就是说,有了 utf8mb4,你想存 Emoji 就存 Emoji,想存啥生僻字就存啥生僻字,再也不用担心乱码的问题了。

utf8utf8mb4 的区别,可以用个表格来总结一下:

特性 utf8 utf8mb4
支持范围 仅支持 BMP (0x0000 – 0xFFFF) 支持所有 Unicode 字符 (0x0000 – 0x10FFFF)
存储空间 1-3 字节 1-4 字节
Emoji支持 不支持 (或者需要特殊处理,比如存成二进制) 完全支持

三、手把手教你升级到 utf8mb4

说了这么多,咱们来点实际的。 怎么把你的数据库、表、列都升级到 utf8mb4 呢? 别怕,很简单,一步一步来。

1. 修改 MySQL 的配置文件

首先,你需要修改 MySQL 的配置文件 (my.cnfmy.ini),告诉 MySQL 用 utf8mb4 作为默认的字符集。 找到 [client][mysql][mysqld] 这几个 section,加上或者修改下面的配置:

[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 # 或者 utf8mb4_general_ci,根据你的需求选择

解释一下这些配置:

  • default-character-set = utf8mb4: 设置客户端和服务器的默认字符集为 utf8mb4
  • character-set-client-handshake = FALSE: 禁用客户端握手时的字符集协商,强制使用服务器端的字符集。 这个选项在一些老版本的 MySQL 上可能需要设置,防止客户端连接时字符集不一致。
  • character-set-server = utf8mb4: 设置服务器的字符集为 utf8mb4
  • collation-server = utf8mb4_unicode_ci: 设置服务器的排序规则。 utf8mb4_unicode_ci 是一个不区分大小写的排序规则,更适合多语言环境。 utf8mb4_general_ci 速度更快,但对某些字符的排序可能不够准确。

改完配置文件,记得重启 MySQL 服务,让配置生效。

2. 修改数据库、表和列的字符集

重启完 MySQL,接下来就要修改你的数据库、表和列的字符集了。 可以用 ALTER 语句来完成:

  • 修改数据库的字符集:

    ALTER DATABASE your_database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

    your_database_name 换成你的数据库名。

  • 修改表的字符集:

    ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

    your_table_name 换成你的表名。 CONVERT TO 会把表里的数据也转换成新的字符集。

  • 修改列的字符集:

    ALTER TABLE your_table_name MODIFY your_column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

    your_table_name 换成你的表名,your_column_name 换成你的列名,VARCHAR(255) 换成你的列的类型和长度。

注意:

  • 修改列的字符集时,一定要指定列的类型和长度,否则 MySQL 会报错。
  • 如果你的表里有大量的历史数据,修改字符集可能会比较慢,需要耐心等待。
  • 修改字符集之前,最好备份一下你的数据库,以防万一。

3. 检查字符集是否修改成功

修改完之后,一定要检查一下字符集是否修改成功了。 可以用 SHOW 语句来查看:

  • 查看数据库的字符集:

    SHOW CREATE DATABASE your_database_name;
  • 查看表的字符集:

    SHOW CREATE TABLE your_table_name;
  • 查看列的字符集:

    SHOW FULL COLUMNS FROM your_table_name;

查看结果里,确认 CHARACTER SETCOLLATION 都是 utf8mb4 和你设置的排序规则,就说明修改成功了。

四、代码示例:一个存 Emoji 的小 Demo

光说不练假把式,咱们来写个小 Demo,演示一下怎么用 utf8mb4 存 Emoji。

import mysql.connector

# 数据库连接配置
config = {
    'user': 'your_user',
    'password': 'your_password',
    'host': 'your_host',
    'database': 'your_database',
    'charset': 'utf8mb4'  # 重点:设置连接字符集为 utf8mb4
}

try:
    # 建立数据库连接
    cnx = mysql.connector.connect(**config)
    cursor = cnx.cursor()

    # 创建表(如果不存在)
    create_table_query = """
    CREATE TABLE IF NOT EXISTS emoji_test (
        id INT AUTO_INCREMENT PRIMARY KEY,
        emoji_text VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
    );
    """
    cursor.execute(create_table_query)
    cnx.commit()

    # 插入 Emoji 数据
    emoji_data = "Hello world! 😊🎉👍"
    insert_query = "INSERT INTO emoji_test (emoji_text) VALUES (%s)"
    cursor.execute(insert_query, (emoji_data,))
    cnx.commit()

    # 查询数据
    select_query = "SELECT * FROM emoji_test"
    cursor.execute(select_query)

    for (id, emoji_text) in cursor:
        print(f"ID: {id}, Emoji Text: {emoji_text}")

except mysql.connector.Error as err:
    print(f"Error: {err}")
finally:
    # 关闭连接
    if cnx:
        cursor.close()
        cnx.close()

代码解释:

  • 这段 Python 代码使用了 mysql.connector 库来连接 MySQL 数据库。
  • 在连接配置里,charset 设置为 utf8mb4,告诉 MySQL 客户端用 utf8mb4 编码来发送和接收数据。
  • 创建表的 SQL 语句里,emoji_text 列的字符集也设置为了 utf8mb4
  • 插入和查询 Emoji 数据,一切都应该顺利进行,不会出现乱码。

五、一些常见问题

  • 升级到 utf8mb4 会影响性能吗?

    utf8mb4utf8 多占用一些存储空间,所以可能会对性能有一定的影响。 但是,对于大多数应用来说,这种影响可以忽略不计。 毕竟,能正确显示 Emoji 和其他 Unicode 字符,比一点点性能更重要。

  • utf8mb4_unicode_ciutf8mb4_general_ci 哪个更好?

    utf8mb4_unicode_ci 更准确,但速度稍慢;utf8mb4_general_ci 速度更快,但对某些字符的排序可能不够准确。 一般来说,如果你的应用需要处理大量的多语言数据,或者对排序的准确性要求比较高,就选择 utf8mb4_unicode_ci;如果对性能要求比较高,可以选择 utf8mb4_general_ci。 也可以根据你的实际情况进行测试,选择最适合你的排序规则。

  • 我可以直接把所有数据库、表和列都改成 utf8mb4 吗?

    理论上可以,但是建议你谨慎操作。 最好先在一个测试环境里进行测试,确保没有问题后再在生产环境里进行修改。 另外,修改字符集之前,一定要备份你的数据库。

  • 我的应用用的是 PHP,怎么设置字符集?

    在 PHP 里,可以用 mysqli_set_charset() 函数来设置字符集:

    <?php
    $mysqli = new mysqli("your_host", "your_user", "your_password", "your_database");
    
    if ($mysqli->connect_errno) {
        echo "Failed to connect to MySQL: " . $mysqli->connect_error;
        exit();
    }
    
    // 设置字符集为 utf8mb4
    if (!$mysqli->set_charset("utf8mb4")) {
        echo "Error loading character set utf8mb4: " . $mysqli->error;
        exit();
    }
    
    // 现在你可以执行 SQL 查询了
    $sql = "SELECT * FROM emoji_test";
    $result = $mysqli->query($sql);
    
    while ($row = $result->fetch_assoc()) {
        echo $row['emoji_text'] . "<br>";
    }
    
    $mysqli->close();
    ?>

六、总结

好啦,今天关于 utf8mb4 和 Emoji 的讲座就到这里了。 总而言之,utf8mb4 是 MySQL 中处理 Unicode 字符的最佳选择,它可以让你轻松存储和处理各种 Emoji 和其他 Unicode 字符,再也不用担心乱码的问题了。 记住,升级到 utf8mb4 需要修改 MySQL 的配置文件、数据库、表和列的字符集,并且要进行充分的测试和备份。

希望今天的讲座对大家有所帮助! 咱们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注