136 lines
3.9 KiB
Markdown
136 lines
3.9 KiB
Markdown
# 修复MySQL数据库注释乱码
|
||
|
||
## 问题描述
|
||
|
||
MySQL数据库表和字段的中文注释显示为乱码,在Navicat等数据库管理工具中查看时出现 `??` 或其他乱码字符。
|
||
|
||
## 诊断方法
|
||
|
||
```bash
|
||
# 检查字段注释的十六进制编码
|
||
mysql -h <host> -P <port> -u <user> -p<password> "<database>" -e "
|
||
SELECT COLUMN_NAME, HEX(COLUMN_COMMENT) as comment_hex
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA='<database>' AND TABLE_NAME='<table_name>';
|
||
"
|
||
```
|
||
|
||
**判断标准:**
|
||
|
||
- ✅ 正确的UTF-8中文:以 `E4`-`E9` 开头(如 `E698AF` = `是`)
|
||
- ❌ 错误编码:以 `C3` 开头(表示双重编码问题)
|
||
|
||
## 解决方案
|
||
|
||
### 方法1:创建UTF-8编码的SQL文件(推荐)
|
||
|
||
1. **创建SQL文件**,确保保存为UTF-8编码:
|
||
|
||
```sql
|
||
-- fix_comments.sql
|
||
USE `<database>`;
|
||
SET NAMES utf8mb4;
|
||
|
||
ALTER TABLE `<table_name>` COMMENT = '正确的中文注释';
|
||
|
||
ALTER TABLE `<table_name>`
|
||
MODIFY COLUMN `column1` varchar(50) DEFAULT NULL COMMENT '字段1中文注释',
|
||
MODIFY COLUMN `column2` varchar(50) DEFAULT NULL COMMENT '字段2中文注释',
|
||
-- ... 更多字段
|
||
```
|
||
|
||
2. **使用utf8mb4字符集执行**:
|
||
|
||
```bash
|
||
mysql -h <host> -P <port> -u <user> -p<password> \
|
||
--default-character-set=utf8mb4 "<database>" < fix_comments.sql
|
||
```
|
||
|
||
### 方法2:验证SQL文件编码
|
||
|
||
```bash
|
||
# 检查文件是否为UTF-8编码
|
||
file fix_comments.sql
|
||
# 应该输出: Unicode text, UTF-8 text
|
||
```
|
||
|
||
### 方法3:通过heredoc创建SQL文件(跨平台)
|
||
|
||
```bash
|
||
cat > fix_comments.sql << 'SQLEOF'
|
||
USE `your_database`;
|
||
SET NAMES utf8mb4;
|
||
ALTER TABLE your_table MODIFY COLUMN your_column varchar(10) DEFAULT NULL COMMENT '正确的中文注释';
|
||
SQLEOF
|
||
```
|
||
|
||
## 验证修复结果
|
||
|
||
```bash
|
||
# 查看表注释
|
||
mysql -h <host> -u <user> -p<password> "<database>" -e "
|
||
SELECT table_name, HEX(table_comment) as comment_hex
|
||
FROM information_schema.tables
|
||
WHERE table_schema='<database>' AND table_name='<table_name>';
|
||
"
|
||
|
||
# 查看字段注释
|
||
mysql -h <host> -u <user> -p<password> "<database>" -e "
|
||
SELECT COLUMN_NAME, COLUMN_COMMENT
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA='<database>' AND TABLE_NAME='<table_name>'
|
||
ORDER BY ORDINAL_POSITION;
|
||
"
|
||
|
||
# 检查是否还有乱码字段(C3开头)
|
||
mysql -h <host> -u <user> -p<password> "<database>" -e "
|
||
SELECT COUNT(*) as bad_comments
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA='<database>' AND TABLE_NAME='<table_name>'
|
||
AND HEX(COLUMN_COMMENT) REGEXP '^C3';
|
||
"
|
||
```
|
||
|
||
## 常见错误及原因
|
||
|
||
| 错误现象 | 原因 | 解决方案 |
|
||
|----------------------|----------------------------|-----------------------|
|
||
| `C3A6CB9C...` (C3开头) | 双重编码:UTF-8被当作GBK处理后再转UTF-8 | 使用UTF-8文件 + utf8mb4执行 |
|
||
| Windows命令行显示乱码 | 终端编码问题,数据库实际正确 | 用HEX()验证实际存储 |
|
||
| SQL文件执行后仍乱码 | 文件未保存为UTF-8 | 用`file`命令检查编码 |
|
||
|
||
## 最佳实践
|
||
|
||
1. **所有SQL文件使用UTF-8编码保存**
|
||
2. **始终使用 `--default-character-set=utf8mb4` 参数**
|
||
3. **在SQL开头添加 `SET NAMES utf8mb4;`**
|
||
4. **用HEX()验证而非肉眼判断**
|
||
5. **批量修复时用脚本生成SQL文件**
|
||
|
||
## 示例:批量生成修复SQL
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# 为指定表生成修复SQL
|
||
|
||
DB_NAME="your_database"
|
||
TABLE_NAME="your_table"
|
||
|
||
cat > fix_${TABLE_NAME}_comments.sql << SQLEOF
|
||
USE \`${DB_NAME}\`;
|
||
SET NAMES utf8mb4;
|
||
|
||
ALTER TABLE \`${TABLE_NAME}\`
|
||
COMMENT = '表的中文名称';
|
||
|
||
ALTER TABLE \`${TABLE_NAME}\`
|
||
MODIFY COLUMN \`id\` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||
MODIFY COLUMN \`name\` varchar(100) DEFAULT NULL COMMENT '名称',
|
||
-- 添加更多字段...
|
||
SQLEOF
|
||
|
||
# 执行修复
|
||
mysql -h localhost -u root -p${DB_PASS} \
|
||
--default-character-set=utf8mb4 "${DB_NAME}" < fix_${TABLE_NAME}_comments.sql
|
||
```
|