MySQL字符编码更改。是否保留数据完整性?

时间:2018-10-24 10:32:44

标签: mysql character-encoding data-integrity

我将不得不将数据库编码从latin-1转换为utf-8。

我知道通过以下命令完成数据库转换的事实

ALTER DATABASE db_name
    [[DEFAULT] CHARACTER SET charset_name]
    [[DEFAULT] COLLATE collation_name]

Source并通过以下命令完成对现有表的转换

ALTER TABLE tbl_name
    [[DEFAULT] CHARACTER SET charset_name]
    [COLLATE collation_name]

Source

但是,数据库已经存在,并且涉及敏感信息。我的问题是我已经拥有的数据是否会更改。这个问题的目的是在进行更改之前,我必须先进行估算。

1 个答案:

答案 0 :(得分:2)

每个(字符串类型)都有其自己字符集和排序规则元数据。

如果在指定的数据类型时(即上次创建或更改的时间),未明确给出任何字符集/排序规则,则该表的默认字符集和排序规则将用于该列。

如果在指定时未明确指定默认字符集/排序规则,则将使用数据库的默认字符集和排序规则作为表的默认字符。

您在问题中引用的命令只会分别更改数据库和表的默认字符集/排序规则。换句话说,它们只会影响之后创建的表和列,而不会影响现有的列(或数据)。

要更新现有数据,您应该先阅读ALTER TABLE上手册页的Changing the Character Set部分:

  

更改字符集

     

要将表的默认字符集和所有字符列(CHARVARCHARTEXT)更改为新字符集,请使用如下语句:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
     

该语句还更改所有字符列的排序规则。如果您没有指定COLLATE子句来指示要使用的排序规则,则该语句将默认排序规则用于字符集。如果此排序规则不适合表的预期用途(例如,如果将其从区分大小写的排序规则更改为不区分大小写的排序规则),则显式指定排序规则。

     

对于数据类型为VARCHARTEXT类型之一的列,CONVERT TO CHARACTER SET根据需要更改数据类型,以确保新列足够长以存储与原始列一样多的字符。例如,一个TEXT列有两个长度的字节,它们存储该列中值的字节长度,最大为65,535。对于latin1 TEXT列,每个字符需要一个字节,因此该列最多可以存储65,535个字符。如果将列转换为utf8,则每个字符最多可能需要三个字节,最大可能长度为3×65,535 = 196,605字节。该长度不适合TEXT列的长度字节,因此MySQL会将数据类型转换为MEDIUMTEXT,这是长度字节可以记录196,605值的最小字符串类型。同样,VARCHAR列可能会转换为MEDIUMTEXT

     

为避免数据类型更改为刚刚描述的类型,请不要使用CONVERT TO CHARACTER SET。而是使用MODIFY更改各个列。例如:

ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8;
ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M) CHARACTER SET utf8;
     

如果指定CONVERT TO CHARACTER SET binary,则CHARVARCHARTEXT列将转换为它们相应的二进制字符串类型(BINARY,{{3 }},VARBINARY)。这意味着这些列将不再具有字符集属性,并且随后的CONVERT TO操作将不适用于它们。

     

如果在charset_name操作中 DEFAULT CONVERT TO CHARACTER SET,则BLOB系统命名的字符集变量。

     
    

警告

         

CONVERT TO操作在原始字符集和命名字符集之间转换列值。如果您在一个字符集中有一列(例如latin1),这不是您想要的,但是存储的值实际上使用其他不兼容的字符集(例如utf8) 。在这种情况下,您必须为每个此类列执行以下操作:

ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
         

之所以可行,是因为您在character_set_database列之间进行转换时没有任何转换。

  
     

要仅更改表的默认字符集,请使用以下语句:

ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name;
     

DEFAULT一词是可选的。默认字符集是如果不为稍后添加到表中的列指定字符集(例如,使用ALTER TABLE ... ADD column)时使用的字符集。

     

启用BLOB系统变量(这是默认设置)时,不允许在包含用于外键约束的字符串列的表上进行字符集转换。解决方法是在执行字符集转换之前禁用foreign_key_checks。重新启用foreign_key_checks之前,必须对涉及外键约束的两个表都执行转换。如果仅在转换一个表之后重新启用foreign_key_checks,则由于在这些操作期间发生隐式转换,ON DELETE CASCADEON UPDATE CASCADE操作可能会破坏引用表中的数据(错误号# 45290,错误#74816)。