我将不得不将数据库编码从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]
但是,数据库已经存在,并且涉及敏感信息。我的问题是我已经拥有的数据是否会更改。这个问题的目的是在进行更改之前,我必须先进行估算。
答案 0 :(得分:2)
每个(字符串类型)列都有其自己字符集和排序规则元数据。
如果在指定列的数据类型时(即上次创建或更改的时间),未明确给出任何字符集/排序规则,则该表的默认字符集和排序规则将用于该列。
如果在指定表时未明确指定默认字符集/排序规则,则将使用数据库的默认字符集和排序规则作为表的默认字符。
您在问题中引用的命令只会分别更改数据库和表的默认字符集/排序规则。换句话说,它们只会影响之后创建的表和列,而不会影响现有的列(或数据)。
要更新现有数据,您应该先阅读ALTER TABLE
上手册页的Changing the Character Set部分:
更改字符集
要将表的默认字符集和所有字符列(
CHAR
,VARCHAR
,TEXT
)更改为新字符集,请使用如下语句:ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
该语句还更改所有字符列的排序规则。如果您没有指定
COLLATE
子句来指示要使用的排序规则,则该语句将默认排序规则用于字符集。如果此排序规则不适合表的预期用途(例如,如果将其从区分大小写的排序规则更改为不区分大小写的排序规则),则显式指定排序规则。对于数据类型为
VARCHAR
或TEXT
类型之一的列,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
,则CHAR
,VARCHAR
和TEXT
列将转换为它们相应的二进制字符串类型(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 CASCADE
或ON UPDATE CASCADE
操作可能会破坏引用表中的数据(错误号# 45290,错误#74816)。