一、字符集utf8mb4和utf8

在MySQL中,字符集utf8mb4和utf8(实际为utf8mb3)的主要区别在于编码范围、存储空间、兼容性以及应用场景。以下是两者的具体对比:

1. 编码范围

  • utf8(utf8mb3):
    • 仅支持基本多语言平面(BMP)的字符,即Unicode码点范围为U+0000到U+FFFF。
    • 无法存储需要4字节编码的字符,例如部分表情符号(Emoji)、罕见汉字、新增Unicode字符等。
  • utf8mb4:
    • 支持完整的Unicode字符集,包括所有17个平面,码点范围为U+0000到U+10FFFF。
    • 可以存储Emoji、罕见汉字、古代文字等特殊字符。

2. 存储空间

  • utf8(utf8mb3):
    • 每个字符使用1~3字节编码。
    • 存储常见字符(如英文、中文)时空间效率较高。
  • utf8mb4:
    • 每个字符使用1~4字节编码。
    • 存储4字节字符(如Emoji)时占用更多空间。例如:
      • CHAR(10)字段在utf8下需预留10*3=30字节。
      • 在utf8mb4下需预留10*4=40字节。

3. 兼容性

  • utf8(utf8mb3):
    • 兼容性更广,几乎所有系统和编程语言均支持。
    • 适合与其他系统(尤其是旧系统)交换数据。
  • utf8mb4:
    • 需要MySQL 5.5.3及以上版本支持。
    • 应用程序和数据库驱动需明确支持utf8mb4,否则可能报错或乱码。

4. 应用场景

  • 优先选utf8(utf8mb3):
    • 仅存储英文、中文等常见字符。
    • 对存储空间敏感,或需兼容旧系统。
  • 优先选utf8mb4:
    • 存储用户生成内容(如评论、社交动态),可能包含Emoji或特殊符号。
    • 开发国际化应用,需支持多语言和罕见字符。
    • 未来扩展性强,避免后续字符集升级麻烦。

5. 排序规则(Collation)差异

  • utf8_general_ci:
    • 比较字符串时不区分大小写和重音,但仅支持BMP字符。
  • utf8mb4_unicode_ci:
    • 基于Unicode标准排序,支持所有字符,准确性更高。
    • 例如:在utf8mb4_unicode_ci下,a和A的比较更符合语言习惯。

6. 安全性

  • utf8(utf8mb3):
    • 存在潜在安全风险,如UTF-8编码注入攻击(利用4字节字符拆分绕过安全检查)。
  • utf8mb4:
    • 严格校验4字节字符,可防止此类攻击。

设置建议

  1. 新建数据库/表时:
    CREATE DATABASE mydb 
    CHARACTER SET utf8mb4 
    COLLATE utf8mb4_unicode_ci;
    
    
    CREATE TABLE mytable (
    id INT PRIMARY KEY,
    content TEXT
    ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

  2. 连接字符串中指定字符集(以JDBC为例):
    jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8mb4

总结

特性utf8(utf8mb3)utf8mb4
编码范围BMP(U+0000~U+FFFF)所有Unicode(U+0000~U+10FFFF)
存储空间1~3字节/字符1~4字节/字符
兼容性高(广泛支持)需MySQL 5.5.3+及驱动支持
Emoji支持❌ 不支持✔️ 支持
安全性存在编码注入风险更安全
适用场景常见字符、兼容旧系统全球语言、特殊符号、未来扩展

建议优先使用utf8mb4,除非明确只需存储BMP字符且需极致压缩空间。

二、区分:utf8mb4_general_ci、utf8mb4_unicode_ci 和 utf8_general_ci 

在MySQL中,utf8mb4_general_ci、utf8mb4_unicode_ci 和 utf8_general_ci 是三种不同的排序规则(Collation),它们决定了字符串的比较和排序方式。以下是它们的区别:

1. 定义与特点

排序规则特点
utf8mb4_general_ci- 不区分大小写(Case Insensitive)
- 不区分重音符号(Accent Insensitive)
- 使用简化的排序算法,速度快但准确性较低
- 适合性能敏感的场景
utf8mb4_unicode_ci- 基于Unicode标准(Unicode Collation Algorithm)
- 区分大小写和重音符号
- 支持多语言和特殊字符的精确排序
- 准确性高但性能稍低
utf8_general_ci- 不区分大小写
- 仅支持基本多语言平面(BMP)字符
- 适用于拉丁字符为主的场景

2. 性能对比

  • utf8mb4_general_ci:
    • 最快,因为它使用简化的排序算法,忽略重音和大小写差异。
    • 适合对性能要求高、但不需要严格排序的场景。
  • utf8mb4_unicode_ci:
    • 较慢,因为它遵循Unicode标准,处理复杂字符时计算量更大。
    • 适合需要精确排序的多语言场景。
  • utf8_general_ci:
    • 性能与utf8mb4_general_ci接近,但仅支持BMP字符。

3. 语言支持

  • utf8mb4_general_ci:
    • 对非拉丁字符(如中文、日文)的排序可能不准确。
    • 例如:café 和 cafe 会被视为相同。
  • utf8mb4_unicode_ci:
    • 支持所有Unicode字符,包括Emoji和罕见汉字。
    • 严格区分重音符号和大小写,例如:café 和 cafe 会被视为不同。
  • utf8_general_ci:
    • 仅支持BMP字符,无法处理Emoji等4字节字符。

4. 使用场景推荐

排序规则适用场景
utf8mb4_general_ci- 英文或简单字符为主的场景
- 需要高性能且对排序准确性要求不高
utf8mb4_unicode_ci- 国际化应用(支持多语言)
- 需要精确排序(如德语、法语)
- 包含Emoji或特殊字符
utf8_general_ci- 兼容旧系统(仅处理BMP字符)
- 明确不需要支持Emoji等特殊字符

5. 示例对比

-- 使用 utf8mb4_general_ci
SELECT 'apple' = 'Apple'; -- 返回 1(相同)
SELECT 'café' = 'cafe'; -- 返回 1(相同)


-- 使用 utf8mb4_unicode_ci
SELECT 'apple' = 'Apple'; -- 返回 0(不同)
SELECT 'café' = 'cafe'; -- 返回 0(不同)


-- 使用 utf8_general_ci
SELECT 'apple' = 'Apple'; -- 返回 1(相同)
SELECT '😊' = '😊'; -- 可能报错(取决于MySQL版本)

总结

特性utf8mb4_general_ciutf8mb4_unicode_ciutf8_general_ci
字符集utf8mb4utf8mb4utf8(仅BMP)
大小写敏感❌ 不敏感✔️ 敏感❌ 不敏感
重音敏感❌ 不敏感✔️ 敏感❌ 不敏感
性能⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
语言支持基础多语言(拉丁字符为主)全Unicode(多语言+特殊字符)仅BMP字符
适用场景英文/简单字符、高性能需求国际化应用、精确排序需求兼容旧系统、仅BMP字符

建议:1. 一般用utf8mb4_general_ci足够了;

   2. 如果更精确的大小写敏感用 utf8mb4_unicode_ci 。

        

(望各位潘安、各位子健/各位彦祖、于晏不吝赐教!多多指正!🙏)

更多推荐