1. 首页 > MySQL教程 > 正文

MySQL教程FG035-MySQL字符集配置与优化

Part01-基础概念与理论知识

1.1 字符集的概念与重要性

字符集是一组字符的集合,包括字母、数字、符号等,用于存储和处理不同语言的字符。合理的字符集配置可以确保数据的正确存储和显示,避免乱码问题,并优化查询性能。更多学习教程www.fgedu.net.cn

1.2 MySQL支持的字符集

MySQL支持多种字符集,包括UTF-8、Latin1、GBK等,不同字符集支持的字符范围和存储大小各不相同。

# 查看MySQL支持的所有字符集
mysql -u root -p -e “SHOW CHARACTER SET;”
Enter password: Fgedu123!
+———-+———————————+———————+——–+
| Charset | Description | Default collation | Maxlen |
+———-+———————————+———————+——–+
| armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 |
| ascii | US ASCII | ascii_general_ci | 1 |
| big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 |
| binary | Binary pseudo charset | binary | 1 |
| cp1250 | Windows Central European | cp1250_general_ci | 1 |
| cp1251 | Windows Cyrillic | cp1251_general_ci | 1 |
| cp1256 | Windows Arabic | cp1256_general_ci | 1 |
| cp1257 | Windows Baltic | cp1257_general_ci | 1 |
| cp850 | DOS West European | cp850_general_ci | 1 |
| cp852 | DOS Central European | cp852_general_ci | 1 |
| cp866 | DOS Russian | cp866_general_ci | 1 |
| cp932 | SJIS for Windows Japanese | cp932_japanese_ci | 2 |
| dec8 | DEC West European | dec8_swedish_ci | 1 |
| eucjpms | UJIS for Windows Japanese | eucjpms_japanese_ci | 3 |
| euckr | EUC-KR Korean | euckr_korean_ci | 2 |
| gb18030 | China National Standard GB18030 | gb18030_chinese_ci | 4 |
| gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | 2 |
| gbk | GBK Simplified Chinese | gbk_chinese_ci | 2 |
| geostd8 | GEOSTD8 Georgian | geostd8_general_ci | 1 |
| greek | ISO 8859-7 Greek | greek_general_ci | 1 |
| hebrew | ISO 8859-8 Hebrew | hebrew_general_ci | 1 |
| hp8 | HP West European | hp8_english_ci | 1 |
| keybcs2 | DOS Kamenicky Czech-Slovak | keybcs2_general_ci | 1 |
| koi8r | KOI8-R Relcom Russian | koi8r_general_ci | 1 |
| koi8u | KOI8-U Ukrainian | koi8u_general_ci | 1 |
| latin1 | cp1252 West European | latin1_swedish_ci | 1 |
| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |
| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |
| latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 |
| macce | Mac Central European | macce_general_ci | 1 |
| macroman | Mac West European | macroman_general_ci | 1 |
| sjis | Shift-JIS Japanese | sjis_japanese_ci | 2 |
| swe7 | 7bit Swedish | swe7_swedish_ci | 1 |
| tis620 | TIS620 Thai | tis620_thai_ci | 1 |
| ucs2 | UCS-2 Unicode | ucs2_general_ci | 2 |
| ujis | EUC-JP Japanese | ujis_japanese_ci | 3 |
| utf16 | UTF-16 Unicode | utf16_general_ci | 4 |
| utf16le | UTF-16LE Unicode | utf16le_general_ci | 4 |
| utf32 | UTF-32 Unicode | utf32_general_ci | 4 |
| utf8 | UTF-8 Unicode | utf8_general_ci | 3 |
| utf8mb4 | UTF-8 Unicode | utf8mb4_0900_ai_ci | 4 |
+———-+———————————+———————+——–+

1.3 排序规则的概念

排序规则是用于比较字符的规则,决定了字符的排序顺序和比较方式。不同的排序规则会影响字符串比较、排序和聚合操作的结果。

# 查看utf8mb4字符集的所有排序规则
mysql -u root -p -e “SHOW COLLATION LIKE ‘utf8mb4%’;”
Enter password: Fgedu123!
+—————————-+———+—–+———+———-+———+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+—————————-+———+—–+———+———-+———+
| utf8mb4_0900_ai_ci | utf8mb4 | 255 | Yes | Yes | 0 |
| utf8mb4_0900_as_ci | utf8mb4 | 305 | | Yes | 0 |
| utf8mb4_0900_as_cs | utf8mb4 | 278 | | Yes | 0 |
| utf8mb4_0900_bin | utf8mb4 | 309 | | Yes | 1 |
| utf8mb4_croatian_ci | utf8mb4 | 245 | | Yes | 8 |
| utf8mb4_czech_ci | utf8mb4 | 234 | | Yes | 8 |
| utf8mb4_danish_ci | utf8mb4 | 235 | | Yes | 8 |
| utf8mb4_estonian_ci | utf8mb4 | 236 | | Yes | 8 |
| utf8mb4_general_ci | utf8mb4 | 45 | | Yes | 1 |
| utf8mb4_german2_ci | utf8mb4 | 244 | | Yes | 8 |
| utf8mb4_hungarian_ci | utf8mb4 | 242 | | Yes | 8 |
| utf8mb4_icelandic_ci | utf8mb4 | 237 | | Yes | 8 |
| utf8mb4_latvian_ci | utf8mb4 | 238 | | Yes | 8 |
| utf8mb4_lithuanian_ci | utf8mb4 | 239 | | Yes | 8 |
| utf8mb4_persian_ci | utf8mb4 | 240 | | Yes | 8 |
| utf8mb4_polish_ci | utf8mb4 | 241 | | Yes | 8 |
| utf8mb4_romanian_ci | utf8mb4 | 243 | | Yes | 8 |
| utf8mb4_roman_ci | utf8mb4 | 250 | | Yes | 8 |
| utf8mb4_sinhala_ci | utf8mb4 | 254 | | Yes | 8 |
| utf8mb4_slovak_ci | utf8mb4 | 246 | | Yes | 8 |
| utf8mb4_slovenian_ci | utf8mb4 | 247 | | Yes | 8 |
| utf8mb4_spanish2_ci | utf8mb4 | 248 | | Yes | 8 |
| utf8mb4_spanish_ci | utf8mb4 | 249 | | Yes | 8 |
| utf8mb4_swedish_ci | utf8mb4 | 252 | | Yes | 8 |
| utf8mb4_tolower_ci | utf8mb4 | 251 | | Yes | 1 |
| utf8mb4_turkish_ci | utf8mb4 | 253 | | Yes | 8 |
| utf8mb4_unicode_520_ci | utf8mb4 | 231 | | Yes | 8 |
| utf8mb4_unicode_ci | utf8mb4 | 224 | | Yes | 8 |
| utf8mb4_unicode_nopad_ci | utf8mb4 | 307 | | Yes | 8 |
| utf8mb4_vietnamese_ci | utf8mb4 | 256 | | Yes | 8 |
| utf8mb4_zh_0900_as_cs | utf8mb4 | 308 | | Yes | 8 |
+—————————-+———+—–+———+———-+———+

Part02-生产环境规划与建议

2.1 字符集选择策略

在生产环境中,字符集的选择应考虑以下因素:

  • 应用程序需要支持的语言和字符范围
  • 存储空间的需求
  • 查询性能的影响
  • 与其他系统的兼容性
生产环境建议:建议使用utf8mb4字符集,它支持所有Unicode字符,包括emoji表情符号,能够满足现代应用的需求。

2.2 排序规则选择建议

排序规则的选择应根据实际需求:

  • utf8mb4_unicode_ci:基于Unicode标准的排序规则,支持多语言,排序准确
  • utf8mb4_general_ci:通用排序规则,性能较好,但排序准确性略低
  • utf8mb4_bin:二进制排序规则,区分大小写,适用于需要精确比较的场景

Part03-生产环境项目实施方案

3.1 服务器级字符集配置

服务器级字符集配置会影响所有数据库和表的默认字符集设置。学习交流加群风哥微信: itpux-com

# 编辑my.cnf配置文件
vi /etc/my.cnf

# 添加以下配置
[mysqld]
# 服务器默认字符集
character-set-server=utf8mb4
# 服务器默认排序规则
collation-server=utf8mb4_unicode_ci
# 连接字符集
default_authentication_plugin=mysql_native_password
init_connect=’SET NAMES utf8mb4′

# 保存并重启MySQL
systemctl restart mysqld

# 验证服务器字符集配置
mysql -u root -p -e “SHOW VARIABLES LIKE ‘character_set_server’; SHOW VARIABLES LIKE ‘collation_server’;”
Enter password: Fgedu123!
+———————-+———+
| Variable_name | Value |
+———————-+———+
| character_set_server | utf8mb4 |
+———————-+———+
+——————+——————–+
| Variable_name | Value |
+——————+——————–+
| collation_server | utf8mb4_unicode_ci |
+——————+——————–+

3.2 数据库级字符集配置

数据库级字符集配置会影响该数据库中所有表的默认字符集设置。

# 创建数据库时指定字符集
mysql -u root -p -e “CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;”
Enter password: Fgedu123!

# 查看数据库字符集配置
mysql -u root -p -e “SELECT schema_name, default_character_set_name, default_collation_name FROM information_schema.schemata WHERE schema_name = ‘mydb’;”
Enter password: Fgedu123!
+————-+—————————-+————————+
| schema_name | default_character_set_name | default_collation_name |
+————-+—————————-+————————+
| mydb | utf8mb4 | utf8mb4_unicode_ci |
+————-+—————————-+————————+

# 修改数据库字符集
mysql -u root -p -e “ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;”
Enter password: Fgedu123!

3.3 表级与列级字符集配置

可以在表级别和列级别设置字符集,以满足不同列的特殊需求。

# 创建表时指定字符集
mysql -u root -p mydb -e “CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, email VARCHAR(255) NOT NULL, phone VARCHAR(20), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;”
Enter password: Fgedu123!

# 查看表字符集配置
mysql -u root -p mydb -e “SHOW CREATE TABLE users;”
Enter password: Fgedu123!
+——-+——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————-+
| Table | Create Table |
+——-+——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————-+
| users | CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
+——-+——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————-+

# 创建表时指定列级字符集
mysql -u root -p mydb -e “CREATE TABLE products (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, description TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, sku VARCHAR(20) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;”
Enter password: Fgedu123!

3.4 连接字符集配置

连接字符集配置确保客户端与服务器之间的数据传输使用正确的字符集。

# 客户端连接时设置字符集
mysql -u root -p mydb -e “SET NAMES utf8mb4;”
Enter password: Fgedu123!

# 查看当前连接字符集
mysql -u root -p mydb -e “SHOW VARIABLES LIKE ‘character_set%’;”
Enter password: Fgedu123!
+————————–+—————————-+
| Variable_name | Value |
+————————–+—————————-+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+————————–+—————————-+

# 查看连接排序规则
mysql -u root -p mydb -e “SHOW VARIABLES LIKE ‘collation%’;”
Enter password: Fgedu123!
+———————-+——————–+
| Variable_name | Value |
+———————-+——————–+
| collation_connection | utf8mb4_general_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+———————-+——————–+

Part04-生产案例与实战讲解

4.1 字符集转换实战

在实际生产环境中,经常需要将现有数据库或表的字符集转换为utf8mb4。

# 转换表的字符集(包括所有列)
mysql -u root -p mydb -e “ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;”
Enter password: Fgedu123!

# 转换单个列的字符集
mysql -u root -p mydb -e “ALTER TABLE users MODIFY name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;”
Enter password: Fgedu123!

# 生成转换数据库所有表的SQL语句
mysql -u root -p -e “SELECT CONCAT(‘ALTER TABLE ‘, table_schema, ‘.’, table_name, ‘ CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;’) FROM information_schema.tables WHERE table_schema = ‘mydb’;”
Enter password: Fgedu123!
+———————————————————————————————————-+
| CONCAT(‘ALTER TABLE ‘, table_schema, ‘.’, table_name, ‘ CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;’) |
+———————————————————————————————————-+
| ALTER TABLE mydb.users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; |
| ALTER TABLE mydb.products CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; |
+———————————————————————————————————-+

4.2 字符集问题排查案例

当遇到字符集问题时,需要进行全面的检查和排查。

# 检查服务器字符集配置
mysql -u root -p -e “SHOW VARIABLES LIKE ‘character_set%’; SHOW VARIABLES LIKE ‘collation%’;”

# 检查数据库字符集配置
mysql -u root -p -e “SELECT schema_name, default_character_set_name, default_collation_name FROM information_schema.schemata WHERE schema_name = ‘mydb’;”

# 检查表字符集配置
mysql -u root -p -e “SELECT table_name, table_collation FROM information_schema.tables WHERE table_schema = ‘mydb’;”

# 检查列字符集配置
mysql -u root -p -e “SELECT column_name, character_set_name, collation_name FROM information_schema.columns WHERE table_schema = ‘mydb’ AND table_name = ‘users’;”

# 测试字符存储
mysql -u root -p mydb -e “INSERT INTO users (name, email) VALUES (‘测试用户’, ‘test@example.com’), (‘John Doe’, ‘john@example.com’), (‘用户表情😊’, ’emoji@example.com’);”
mysql -u root -p mydb -e “SELECT * FROM users;”
Enter password: Fgedu123!
+—-+————–+——————+——-+———————+
| id | name | email | phone | created_at |
+—-+————–+——————+——-+———————+
| 1 | 测试用户 | test@example.com | NULL | 2024-01-01 00:00:00 |
| 2 | John Doe | john@example.com | NULL | 2024-01-01 00:00:00 |
| 3 | 用户表情😊 | emoji@example.com | NULL | 2024-01-01 00:00:00 |
+—-+————–+——————+——-+———————+

4.3 导入导出字符集处理

在导入导出数据时,需要注意字符集的一致性,避免出现乱码问题。

# 导出数据时指定字符集
mysqldump –default-character-set=utf8mb4 -u root -p mydb > mydb_utf8mb4.sql
Enter password: Fgedu123!

# 查看导出文件的字符集信息
file -i mydb_utf8mb4.sql
mydb_utf8mb4.sql: text/plain; charset=utf-8

# 导入数据时指定字符集
mysql –default-character-set=utf8mb4 -u root -p mydb < mydb_utf8mb4.sql Enter password: Fgedu123! # 使用mysqlimport导入时指定字符集 mysqlimport --default-character-set=utf8mb4 -u root -p mydb data.csv Enter password: Fgedu123!

Part05-风哥经验总结与分享

5.1 字符集配置最佳实践

根据多年的MySQL运维经验,总结以下字符集配置最佳实践:

  • 统一使用utf8mb4字符集,避免多字符集混合使用
  • 在服务器、数据库、表和列级别统一配置字符集
  • 确保客户端连接时使用正确的字符集
  • 在应用程序层面也使用相同的字符集进行处理

5.2 常见问题与解决方案

风哥提示:以下是MySQL字符集配置中常见的问题及解决方案:

# 问题1:插入emoji表情失败
# 错误信息:ERROR 1366 (HY000): Incorrect string value: ‘\xF0\x9F\x98\x81’ for column ‘name’ at row 1
# 解决方案:将列字符集改为utf8mb4
ALTER TABLE users MODIFY name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;

# 问题2:查询结果出现乱码
# 解决方案:检查连接字符集设置
SET NAMES utf8mb4;

# 问题3:字符集转换导致索引失效
# 解决方案:确保查询条件中的字符串与列字符集一致,避免隐式转换
# 错误示例:SELECT * FROM users WHERE name = ‘测试’ COLLATE utf8_general_ci;
# 正确示例:SELECT * FROM users WHERE name = ‘测试’;

# 问题4:排序结果不符合预期
# 解决方案:选择合适的排序规则
ALTER TABLE users MODIFY name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;

5.3 性能优化建议

字符集配置对MySQL性能有一定影响,以下是一些性能优化建议:

  • 选择合适的字符集:根据实际需求选择字符集,避免使用不必要的大字符集
  • 使用前缀索引:对于长字符串字段,使用前缀索引可以减少索引大小
  • 避免字符集转换:确保查询条件与列字符集一致,避免隐式转换导致索引失效
  • 优化LIKE查询:避免前缀通配符,如’%test’,这会导致全表扫描
  • 配置字符集缓存:根据需要调整字符集缓存大小
# 配置字符集缓存大小
vi /etc/my.cnf
[mysqld]
# 字符集缓存大小
character_set_cache_size=1M
# 排序缓存大小
sort_buffer_size=256K

# 重启MySQL使配置生效
systemctl restart mysqld

# 验证配置
mysql -u root -p -e “SHOW VARIABLES LIKE ‘character_set_cache_size’; SHOW VARIABLES LIKE ‘sort_buffer_size’;”
Enter password: Fgedu123!
+————————-+——–+
| Variable_name | Value |
+————————-+——–+
| character_set_cache_size | 1048576 |
+————————-+——–+
+——————+——–+
| Variable_name | Value |
+——————+——–+
| sort_buffer_size | 262144 |
+——————+——–+

风哥经验分享:在生产环境中,字符集配置是一个基础但非常重要的环节。建议在项目初期就统一规划好字符集,避免后期大规模转换带来的风险和性能影响。学习交流加群风哥QQ113257174
GF-MySQL数据库培训文档系列

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息