10.7 列字符集转换
要将二进制或非二进制字符串列转换为使用特定字符集,请使用ALTER TABLE。为了成功进行转换,必须满足以下条件之一:
-
如果列具有二进制数据类型(BINARY,VARBINARY,BLOB),则必须使用单个字符集(将列转换为的字符集)对它包含的所有值进行编码。如果使用二进制列将信息存储在多个字符集中,则 MySQL 无法知道哪些值使用哪个字符集,并且无法正确转换数据。
-
如果列具有非二进制数据类型(CHAR,VARCHAR,TEXT),则其内容应以列字符集而不是其他字符集编码。如果内容以不同的字符集编码,则可以先将该列转换为使用二进制数据类型,然后再转换为具有所需字符集的非二进制列。
假设 tablet
的二进制列col1
定义为VARBINARY(50)
。假设该列中的信息是使用单个字符集编码的,则可以将其转换为具有该字符集的非二进制列。例如,如果col1
包含 table 示greek
字符集中的字符的二进制数据,则可以按以下方式对其进行转换:
ALTER TABLE t MODIFY col1 VARCHAR(50) CHARACTER SET greek;
如果原始列的类型为BINARY(50)
,则可以将其转换为CHAR(50)
,但是结果值将在末尾添加0x00
个字节,这可能是不希望的。要删除这些字节,请使用TRIM()函数:
UPDATE t SET col1 = TRIM(TRAILING 0x00 FROM col1);
假设 tablet
有一个名为col1
的非二进制列,定义为CHAR(50) CHARACTER SET latin1
,但您希望将其转换为使用utf8
,以便可以存储多种语言的值。下面的语句完成了这一点:
ALTER TABLE t MODIFY col1 CHAR(50) CHARACTER SET utf8;
如果该列包含两个字符集中都没有的字符,则转换可能是有损失的。
如果您有 MySQL 4.1 之前的旧 table,则这是一种特殊情况。在该 table 中,非二进制列包含的值实际上是用与服务器默认字符集不同的字符集编码的。例如,即使 MySQL 的默认字符集不同,应用程序也可能在一列中存储了sjis
个值。可以将列转换为使用正确的字符集,但需要执行附加步骤。假设服务器的默认字符集是latin1
,并且col1
定义为CHAR(50)
,但是其内容是sjis
值。第一步是将列转换为二进制数据类型,这将删除现有字符集信息,而无需执行任何字符转换:
ALTER TABLE t MODIFY col1 BLOB;
下一步是使用适当的字符集将列转换为非二进制数据类型:
ALTER TABLE t MODIFY col1 CHAR(50) CHARACTER SET sjis;
此过程要求在升级到 MySQL 4.1 或更高版本后,尚未使用INSERT或UPDATE等语句修改 table。在这种情况下,MySQL 将使用latin1
将新值存储在该列中,并且该列将包含sjis
和latin1
值的混合,并且无法正确转换。
如果在最初创建列时指定了属性,则在用ALTER TABLE更改 table 时也应指定属性。例如,如果您指定NOT NULL
和一个明确的DEFAULT
值,则还应在ALTER TABLE语句中提供它们。否则,结果列定义将不包括那些属性。
要转换 table 中的所有字符列,ALTER TABLE ... CONVERT TO CHARACTER SET charset
语句可能会有用。参见第 13.1.8 节“ ALTER TABLE 语句”。