utf8mb4_0900_ai_ci 和 utf8mb4_unicode_ci 都是有效的 UTF-8 字符集排序规则,但它们有一些重要区别:
utf8mb4_unicode_ci: 基于 Unicode 4.0 标准(较旧)utf8mb4_0900_ai_ci: 基于 Unicode 9.0 标准(更新)utf8mb4_0900_ai_ci 对某些语言的排序更准确,特别是:
utf8mb4_unicode_ci: 稍慢但兼容性好utf8mb4_0900_ai_ci: 性能更优(MySQL 8.0+)ai = accent insensitive(不区分重音)ci = case insensitive(不区分大小写)如果 soe_data 表使用 utf8mb4_0900_ai_ci,而 dispatch_logs 表使用 utf8mb4_unicode_ci,可能会遇到:
-- 这种 JOIN 可能会有警告或性能问题
SELECT *
FROM dispatch_logs d
JOIN soe_data s ON d.equipment_name = s.dev_name
-- 两个表的 collation 不同
MySQL 的处理方式:
-- utf8mb4_unicode_ci 下
'café' = 'cafe' -- false
-- utf8mb4_0900_ai_ci 下(accent insensitive)
'café' = 'cafe' -- true (不区分重音)
-- 将 soe_data 改为与 dispatch_logs 一致
ALTER TABLE soe_data
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
# 在 Perl 代码中的 SQL 查询
my $sql = "SELECT d.*, s.*
FROM dispatch_logs d
JOIN soe_data s
ON d.equipment_name COLLATE utf8mb4_unicode_ci =
s.dev_name COLLATE utf8mb4_unicode_ci";
可以不改的情况:
查看你的 Feeder3568.pm 模块:
# 当前代码中,两表是独立查询的,没有 JOIN
sub _ingest_dispatch_logs { ... } # 查询 dispatch_logs
sub _ingest_soe_data { ... } # 查询 soe_data
好消息: 你的代码中两表是分别查询的,没有直接 JOIN,所以影响较小。
但需要注意:
如果设备名称包含特殊字符(如中文、重音字符),不同的 collation 可能导致:
# dispatch_logs 中的设备名
"10kV某某线"
# soe_data 中的设备名
"10kV某某线" # 看起来一样,但可能因 collation 不同匹配不上
立即检查:
-- 查看 dispatch_logs 的 collation
SHOW CREATE TABLE dispatch_logs;
-- 如果它是 utf8mb4_unicode_ci,建议统一
ALTER TABLE soe_data
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
如果暂时不能修改表结构:
在代码中添加注释标记这个潜在问题,便于后续排查:
# Note: soe_data uses utf8mb4_0900_ai_ci while dispatch_logs uses utf8mb4_unicode_ci
# This may cause issues if tables are joined in the future
# Consider unifying collations if data matching problems occur
对于电网设备名称这种场景,统一使用 utf8mb4_unicode_ci 是更安全的选择,因为它兼容性更好,且 MySQL 5.7+ 都支持。