场景
数据库使用mysql5, 在开发机器上测试过,增删查改都没有问题,然后拉到现网上灰度测试一下,发现部分含有中文的操作结果不符合预期,于是select了一下表里面的内容,发现内容中有许多????,直觉告诉我,charset问题。 然后回归线下,排除了程序的问题后,diff了两台mysql一些配置上的问题。
结果如下:
开发机器上的charset设置
现网机器上的charset设置
google一下关于character_set_client/connection/database/results:
简单摘要
character_set_client 客户端向服务器发送查询时的字符集
character_set_results 服务器向客户端发送数据时的字符集
character_set_connection 服务器将收到的查询串转换为此字符集
character_set_database 数据库默认的字符集
...其他几个掠过...
查了以后,再用show create table xxx 可以确认一下,果然table字符集默认采用了database的gbk。
最后解决,采用alter table 的Charset搞定,注意,如果你的表中已经有数据了,那么你需要自己写工具将数据dump出来再修正后插回去,否则直接这样alter对历史数据是无效的。
感悟
mysql 字符集层次架构非常灵活,但易用性确实差了一点。 层次也太多了,client|result , connection, database, os ; 不仅如此在同一database, 可对不同table,甚至到列作定制,确实超级灵活。
选项太多,出错的机会就更多。 如果只有一个选项,没得选,根本就没出错的机会。
另外,层次如果只有 client,database,os 那会怎样?我个人就觉得超级好理解。如果真有那么奇奇怪怪的需求如同一个系统中有n多种字符集,大可提到逻辑层来做。