我们目前正在将 MySQL 服务器中的 latin1 数据库迁移到 UTF8。
我们正在研究什么是最好的方法,希望不会造成任何停机。
我的问题是,我们是否会将 latin1 数据库中的表迁移到 UTF8,例如,我们有一个查询对这两个表执行操作(例如,联接)
由于不同的排序规则/字符集,我们是否有可能开始得到预期之外的结果?
我想迁移整个数据库会更安全,但会涉及停机时间。
谢谢你。
编辑:
我们正在查看我们的数据,我们发现 99% 的数据是 windows cp1252 编码的数据,这意味着将表从 latin1 转换为 utf8 是安全的,而不必担心损坏它。
所以在我看来,我们有三个选择:
pt-online-schema-change
(或类似的东西)是和不是。
表中的单独的列可以有不同的字符集和排序规则。不能分开行。
表是独立的,直到您
JOIN
。此时,如果您要加入的列没有相同的字符集 和 排序规则,性能就会受到影响。
插入/获取数据时,您的客户端有一个字符集。如果是 utf8mb4,那么 MySQL 会很乐意在该字符与表列中的字符之间进行动态转换。当然,有些字符是不能转换的;例如,latin1 的不同字符比 utf8mb4 少得多。
您提到了移民。您将需要转储并重新加载(较慢)或执行大量更改(更快,但对于大型表来说不是“快”)或执行其他操作。请说明您可以接受的参数。速度、简单性等之间存在权衡。
很多人在更改字符集时都会遇到麻烦。大约有 7 种不同的 ALTER 可供人们使用。如果你执行错误,就会造成一团糟,很难解决。
如果您在更改数据库时尝试保持数据库“活动”,则可能会遇到上面提到的 JOIN 性能问题。
如果您已经设置了复制,则可能有一些利用“故障转移”的技术。
请随身携带以下问答,以防遇到乱码: UTF-8 字符出现问题;我看到的不是我存储的
您使用的 MySQL 版本是什么?如果是 8.0,那么默认字符集 (utf8mb4) 及其默认排序规则可能是最好的。
您不应该得到意想不到的结果。
如果字符集完全不兼容,那么根本无法进行字符串比较。你会得到一个错误。
如果字符集兼容,但排序规则不同,您应该得到相同的结果,但不会通过索引查找进行优化。您可以使用 EXPLAIN 来验证这一点,您将在其中看到连接的表 使用表扫描,并且在额外列中可能有“使用连接缓冲区”。
为了解决停机问题,我使用了pt-online-schema-change来执行
ALTER TABLE <name> CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
(假设您使用的是MySQL 8.0,这对于字符集/排序规则来说是一个不错的选择),同时继续读写原始表。我们每周多次执行此操作(或其他 ALTER TABLE 更改),甚至在高峰时段也是如此。
考虑使用 pt-online-schema-change 似乎是一个安全的选择。我唯一不喜欢的是它会更改 FK 的名称,将 _ 前缀为“FK_NAME”。 2 个问题: #1 有办法解决这个问题吗?
#2 测试列是否正确转换的简单方法是什么?
谢谢。