目录核心区别详细对比1. **编码范围不同**2. **历史背景**3. **实际影响最明显的场景**4. **存储空间差异**5. **性能差异**关键限制**索引长度限制**实际使用建议1. **新项目一律使用utf8mb4**2. **现有系统迁移步骤**3. **连接配置**4. **排序规则选择**兼容性考虑**向下兼容性****客户端兼容性**验证当前设置总结建议核心区别utf8在MySQL中是一个不完整的UTF-8实现而utf8mb4才是真正的UTF-8实现。详细对比1.编码范围不同字符集最大字节数支持的Unicode范围备注utf83字节BMP平面U0000 ~ UFFFF不支持4字节字符utf8mb44字节所有Unicode字符包括Supplementary Planes完整UTF-8支持2.历史背景utf8 (utf8mb3): MySQL早期实现的阉割版UTF-82003年引入当时认为3字节足够表示所有字符实际是UTF-8的一个子集后来更名为utf8mb3utf8mb4: MySQL 5.5.3引入完整的UTF-8实现“mb4” “multi-byte 4”3.实际影响最明显的场景-- 这些字符在utf8下会出错在utf8mb4下正常-- 表情符号EmojiINSERTINTOusers(name)VALUES(小明开心);-- 需要utf8mb4-- 部分生僻汉字INSERTINTOtext(content)VALUES();-- 需要utf8mb4-- 某些数学符号、音乐符号等INSERTINTOsymbols(symbol)VALUES();-- 需要utf8mb44.存储空间差异-- 创建表对比CREATETABLEtest_utf8(idINT,textVARCHAR(100)CHARACTERSETutf8-- 最大300字节);CREATETABLEtest_utf8mb4(idINT,textVARCHAR(100)CHARACTERSETutf8mb4-- 最大400字节);-- 注意VARCHAR(100)对于utf8最多存储100个字符但可能占用最多300字节-- 对于utf8mb4最多存储100个字符但可能占用最多400字节5.性能差异方面utf8utf8mb4说明存储空间较小较大utf8mb4可能多用约33%空间索引长度较短较长索引长度限制以字节为单位排序性能稍快稍慢差异通常不明显关键限制索引长度限制-- utf8: 最大索引长度 767字节-- utf8mb4: 最大索引长度 3072字节MySQL 5.7-- 但在早期版本中InnoDB对utf8mb4的索引限制-- utf8: VARCHAR(255) 可以建索引 (255×3765 767)-- utf8mb4: VARCHAR(255) 不能建索引 (255×41020 767)-- 需要改为 VARCHAR(191) (191×4764 767)-- 解决办法修改innodb_large_prefix设置SETGLOBALinnodb_large_prefixON;SETGLOBALinnodb_file_formatBarracuda;实际使用建议1.新项目一律使用utf8mb4-- 数据库级别CREATEDATABASEmydbCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;-- 表级别CREATETABLEmytable(idINTPRIMARYKEY,contentTEXT)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;-- 列级别ALTERTABLEmytableMODIFYcontentVARCHAR(255)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;2.现有系统迁移步骤-- 1. 备份数据-- 2. 修改数据库默认字符集ALTERDATABASEdatabase_nameCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;-- 3. 修改表字符集ALTERTABLEtable_nameCONVERTTOCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;-- 4. 修改连接配置-- 在my.cnf中[client]default-character-setutf8mb4[mysql]default-character-setutf8mb4[mysqld]character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci-- 5. 验证修改SHOWVARIABLESLIKEcharacter_set%;SHOWVARIABLESLIKEcollation%;3.连接配置# 命令行连接mysql -u root -p --default-character-setutf8mb4# 应用程序连接示例# Python (PyMySQL)connpymysql.connect(charsetutf8mb4)# PHP (PDO)$pdonew PDO(mysql:hostlocalhost;dbnametest;charsetutf8mb4,$user,$pass);# Java (JDBC)jdbc:mysql://localhost:3306/db?characterEncodingutf8mb44.排序规则选择-- 常用排序规则utf8mb4_unicode_ci-- 基于Unicode标准排序支持多语言推荐utf8mb4_general_ci-- 旧的排序规则性能稍好但准确性较差utf8mb4_bin-- 二进制排序区分大小写和重音utf8mb4_0900_ai_ci-- MySQL 8.0默认基于Unicode 9.0标准-- 查看所有utf8mb4排序规则SHOWCOLLATIONLIKEutf8mb4%;兼容性考虑向下兼容性utf8mb4完全兼容utf8utf8mb3存储的数据反向不兼容utf8mb4的数据可能无法在utf8中正常显示客户端兼容性所有现代客户端都支持utf8mb4确保客户端连接时也使用utf8mb4字符集验证当前设置-- 查看数据库、表、列的字符集SELECTTABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,CHARACTER_SET_NAME,COLLATION_NAMEFROMinformation_schema.COLUMNSWHERETABLE_SCHEMAyour_databaseANDCHARACTER_SET_NAMEISNOTNULL;-- 查看当前连接的字符集SHOWVARIABLESWHEREVariable_nameLIKEcharacter_set_%ORVariable_nameLIKEcollation%;总结建议始终使用utf8mb4不要使用utf8排序规则使用utf8mb4_unicode_ci或MySQL 8.0的utf8mb4_0900_ai_ci注意索引长度限制必要时调整字段长度确保应用程序连接字符串也使用utf8mb4MySQL 8.0已将utf8mb4作为默认字符集-- MySQL 8.0默认设置mysqlSELECTcharacter_set_database,collation_database;--------------------------------------------------|character_set_database|collation_database|--------------------------------------------------|utf8mb4|utf8mb4_0900_ai_ci|--------------------------------------------------重要提示MySQL未来版本中utf8可能会被重新定义为真正的UTF-8目前utf8是utf8mb3的别名建议明确使用utf8mb4以避免不确定性。