2011-04-07 15 views
7

我正在使用MySQL数据库服务器运行一个生产应用程序。我忘记将列的排序规则从latin设置为utf8_unicode,这会在保存到具有多语言数据的列时导致奇怪的数据。如果我更改MySQL中列的排序规则,现有数据会发生什么变化?

我的问题是,如果现在将我的排序规则更改为utf8_unicode,现有数据会发生什么情况?它是否会破坏或破坏现有数据或将数据保留,但新数据将保存为utf8

我会改变与phpMyAdmin网络客户端。

回答

4

运行在MySQL 5.1快速测试用VARCHAR列设置为latin1_bin我插入一些非拉丁字符

INSERT INTO Test VALUES ('英國華僑'); 

我选择他们,让垃圾(如预期)。

SELECT text from Test; 

text 
???? 

然后我改变了列的排序规则,以utf8_unicode并重新运行SELECT和它显示了同样的结果

text 
???? 

这正是我所期望的 - 它会保持数据和数据将保持垃圾,因为当数据插入时,列丢失了额外的字符信息,并插入一个?对于每个非拉丁字符,并没有办法为????再次成为英国华侨。

您的数据将保留在原位,但不会被修复。

1

有效数据将被正确地转换:

当您更改使用 变化的数据类型或修改MySQL试图以 将现有列值的 新类型以及可能的。警告: 此转换可能会导致 数据更改。

http://dev.mysql.com/doc/refman/5.5/en/alter-table.html

...更具体地说:

要转换为二进制或者非二进制字符串 列使用特定 字符集,使用ALTER TABLE。为了发生 成功转换, 一个下列条件必须 适用:[...]如果列具有 非二进制数据类型(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并将其转换为“兼容”的东西。数据一旦消失,就无法恢复。

综上所述:

  1. 使用HEX()来找出如果你仍然有你的数据。
  2. 在您的表格副本中进行测试。
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试图保存数据:只要您的数据可以在目标字符集中表示,转换就不会有损。如果数据截断正在进行,将会打印警告,而目标字符集中无法表示的数据将被替换为?

0

我的问题是,如果现在将我的 排序规则更改为utf8_unicode,现有数据会发生什么情况?

回答:如果您更改为utf8_unicode_ci,那么您的现有数据(已损坏并保持损坏,直到您修改它)才会发生什么情况。

将其摧毁或损坏现有数据或将维持数据, 但它应该在新的数据将被保存为UTF8?

答案:更改为utf8_unicode_ci后,现有数据不会被销毁。它会像以前一样(像????一样)。但是,如果插入包含Unicode字符的新数据,它将被正确存储。

我会改变与phpMyAdmin网络客户端。

答:当然,你可以通过以下操作>表选项

0

注意改变与phpMyAdmin整理! 一些问题通过两个步骤的过程

ALTER TABLE ... MODIFY ... VARBINARY... 
ALTER TABLE ... MODIFY ... VARCHAR... 

通过

ALTER TABLE ... CONVERT TO ... 

一些得到解决解决如果你错了,你将有一个更糟糕的乱七八糟

  1. SELECT HEX(col), col ...看看你真的有什么。
  2. 研究这个,看看你有什么情况:Trouble with utf8 characters; what I see is not what I stored
  3. 执行正确的修复,根据这些情况:http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases
相关问题