我正在使用MySQL数据库服务器运行生产应用程序。我忘记将列的排序规则从latin
设置为utf8_unicode
,这会在保存到具有多语言数据的列时导致奇怪的数据。
我的问题是,如果我现在将校对更改为utf8_unicode,我的现有数据会发生什么?它会破坏或破坏现有数据还是数据仍然存在,但新数据将保存为utf8
应该是什么?
我将使用phpMyAdmin网络客户端进行更改。
答案 0 :(得分:6)
文章http://mysqldump.azundris.com/archives/60-Handling-character-sets.html详细讨论了这一点,并展示了将会发生的事情。
请注意,您正在将CHARACTER SET(实际上是编码)与COLLATION混合。
字符集定义磁盘上字符串的物理表示形式。您可以使用HEX()函数(例如SELECT HEX(str) FROM t WHERE id = 1
)使其可见,以查看MySQL如何存储字符串的字节。 MySQL提供给您的内容可能会有所不同,具体取决于您使用SET NAMES ....
定义的连接的字符集。
排序规则是排序顺序。它取决于字符集。例如,您的数据可能是latin1字符集,但可以根据两个德语排序顺序latin1_german1_ci或latin1_german2_ci中的任何一个进行排序。根据您的选择,诸如ö的元音符号将分为oe或o。
更改字符集时,需要重写表中的数据。 MySQL将读取表中的所有数据和所有索引,制作临时占用磁盘空间的表的隐藏副本,然后将旧表移动到隐藏位置,将隐藏表移动到位,然后删除旧数据,释放磁盘空间。在中间的一段时间内,你需要两倍的存储空间。
更改排序规则时,数据的排序顺序会更改,但不会更改数据本身。如果您要更改的列不是索引的一部分,除了重写frm文件之外不需要做任何事情,并且MySQL的最新版本不应该做更多。
当您更改作为索引一部分的列的排序规则时,需要重写索引,因为索引是表的排序摘录。这将再次触发上面概述的ALTER TABLE表复制逻辑。
MySQL会尝试保留这样做的数据:只要您拥有的数据可以在目标字符集中表示,转换就不会有损。如果发生数据截断,将打印警告,并且目标字符集中无法表示的数据将替换为?
答案 1 :(得分:4)
在MySQL 5.1中运行快速测试,VARCHAR列设置为latin1_bin
我插入了一些非拉丁字符
INSERT INTO Test VALUES ('英國華僑');
我选择它们并得到垃圾(如预期的那样)。
SELECT text from Test;
给出
text
????
然后我将列的排序规则更改为utf8_unicode
并重新运行SELECT并显示相同的结果
text
????
这就是我所期望的 - 它将保持数据和数据仍然是垃圾,因为当插入数据时,列丢失了额外的字符信息,只是插入了一个?对于每个非拉丁字符并没有办法????再次成为英国华侨。
您的数据将保留在原位,但不会修复。
答案 2 :(得分:1)
有效的数据将被正确转换:
使用时更改数据类型 更改或修改,MySQL尝试 将现有列值转换为 新型也是可能的。警告: 这种转换可能会导致 改变数据。
http://dev.mysql.com/doc/refman/5.5/en/alter-table.html
......更具体地说:
转换二进制或非二进制 字符串列使用特定的 字符集,使用ALTER TABLE。对于 成功转换发生之一 必须满足以下条件 apply:[...]如果列有一个 非二进制数据类型(CHAR,VARCHAR, TEXT),其内容应编码 在列字符集中,不是一些 其他字符集。如果是内容 以不同的字符编码 设置,您可以转换要使用的列 首先是二进制数据类型,然后是 具有所需的非二进制列 字符集。
http://dev.mysql.com/doc/refman/5.1/en/charset-conversion.html
因此,您的问题是无效的数据,例如,以不同字符集编码的数据。我已经尝试过文档建议的提示,它基本上破坏了我的数据,但原因是我的数据已经丢失:运行SELECT column, HEX(column) FROM table
显示多字节字符已插入为0x3F
(即, Latin1中的?
符号。我的MySQL堆栈非常智能,可以检测到输入数据不是Latin1并将其转换为“兼容”的东西。一旦数据消失,你无法取回它。
总结一下:
答案 3 :(得分:0)
我的问题是,如果我改变了我的现有数据将会发生什么 现在整理到utf8_unicode? p>
答案:如果您更改为utf8_unicode_ci,您的现有数据(已经损坏并且在您修改之前仍然会损坏)将发生任何事情。
它会破坏或破坏现有数据还是数据仍然存在, 但新数据将保存为utf8应该是什么?
答案:更改为utf8_unicode_ci后,现有数据不会被销毁。它将像以前一样保持不变(像????)。但是,如果插入包含Unicode字符的新数据,则会正确存储。
我将使用phpMyAdmin网络客户端进行更改。
答案:当然,您可以通过转到操作>更改与phpMyAdmin的排序规则。表格选项
答案 4 :(得分:0)
小心! 一些问题通过
解决ALTER TABLE ... CONVERT TO ...
部分通过两步流程解决
ALTER TABLE ... MODIFY ... VARBINARY...
ALTER TABLE ... MODIFY ... VARCHAR...
如果你做错了,你会有一个更糟的混乱!
SELECT HEX(col), col ...
查看您的真实情况。