我必须将数据库编码从拉丁-1转换为utf-8。
我知道转换数据库是通过
ALTER DATABASE db_name
[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]
通过
ALTER TABLE tbl_name
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]
来源。
然而,该数据库已经存在,而且涉及敏感信息。我的问题是我已有的数据是否会改变。这个问题的目的是我必须在做改变之前给出一个估计。
1条答案
按热度按时间zwghvu4y1#
每个(字符串类型)列都有自己的字符集和排序规则元数据。
如果在指定列的数据类型时(即上次创建或更改时),没有显式给出字符集/排序规则,则表的默认字符集和排序规则将用于该列。
如果在指定表时,没有显式给出默认字符集/排序规则,则数据库的默认字符集和排序规则将用于表的默认字符集和排序规则。
您在问题中引用的命令只是分别更改数据库和表的默认字符集/排序规则。换句话说,它们只会影响以后创建的表和列,而不会影响现有的列(或数据)。
要更新现有数据,应首先阅读上手册页的“更改字符集”部分
ALTER TABLE
:更改角色集
更改表格默认字符集和所有字符列的步骤(
CHAR
,VARCHAR
,TEXT
)要创建新的字符集,请使用以下语句:该语句还更改所有字符列的排序规则。如果您指定否
COLLATE
子句来指示要使用的排序规则,该语句对字符集使用默认排序规则。如果此排序规则不适合预期的表用途(例如,如果它将从区分大小写的排序规则更改为不区分大小写的排序规则),请显式指定排序规则。对于数据类型为的列
VARCHAR
或者一个TEXT
类型,CONVERT TO CHARACTER SET
根据需要更改数据类型,以确保新列的长度足以存储与原始列一样多的字符。例如,一个TEXT
列有两个长度字节,用于存储列中值的字节长度,最大值为65535。为了一个latin1
TEXT
列中,每个字符需要一个字节,因此该列最多可以存储65535个字符。如果列转换为utf8
,每个字符可能需要最多3个字节,最大可能长度为3× 65535=196605字节。这个长度不适合一个房间TEXT
列的长度字节,因此mysql将数据类型转换为MEDIUMTEXT
,这是长度字节可以记录值196605的最小字符串类型。类似地,一个VARCHAR
列可能转换为MEDIUMTEXT
.为避免更改刚才描述的数据类型,请不要使用
CONVERT TO CHARACTER SET
. 相反,使用MODIFY
更改单个列。例如:如果您指定
CONVERT TO CHARACTER SET binary
,的CHAR
,VARCHAR
,和TEXT
列被转换为相应的二进制字符串类型(BINARY
,VARBINARY
,BLOB
). 这意味着列将不再具有字符集属性和后续属性CONVERT TO
操作将不适用于它们。如果
charset_name
是DEFAULT
在一个CONVERT TO CHARACTER SET
操作,由character_set_database
使用系统变量。警告
这个
CONVERT TO
操作在原始字符集和命名字符集之间转换列值。如果在一个字符集中有一列(如latin1
)但是存储的值实际上使用了其他一些不兼容的字符集(比如utf8
). 在这种情况下,您必须对每个此类列执行以下操作:这样做的原因是在转换到或从时没有转换
BLOB
柱。要仅更改表的默认字符集,请使用以下语句:
这个词
DEFAULT
是可选的。默认字符集是在不为以后添加到表中的列指定字符集时使用的字符集(例如,使用ALTER TABLE ... ADD column
).当
foreign_key_checks
如果启用系统变量(这是默认设置),则不允许在包含外键约束中使用的字符串列的表上进行字符集转换。解决方法是禁用foreign_key_checks
在执行字符集转换之前。在重新启用之前,必须对外键约束中涉及的两个表执行转换foreign_key_checks
. 如果重新启用foreign_key_checks
在只转换其中一个表之后ON DELETE CASCADE
或者ON UPDATE CASCADE
由于在这些操作期间发生的隐式转换(bug#45290、bug#74816),操作可能会损坏引用表中的数据。