12.7 列字符集转换
要将二进制或非二进制字符串列转换为使用特定的字符集,使用ALTER TABLE。为了成功转换,必须满足以下条件之一:
假设表格t有一个二进制列名为col1,定义为VARBINARY(50)。假设该列的信息使用单个字符集编码,你可以将其转换到非二进制列,该列具有该字符集。例如,如果col1包含在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);
假设表格t有一个非二进制列名为col1,定义为CHAR(50) CHARACTER SET latin1,但是你想将其转换到使用utf8mb4,以便存储多种语言的值。以下语句实现了这个目标:
ALTER TABLE t MODIFY col1 CHAR(50) CHARACTER SET utf8mb4;
转换可能会丢失如果该列包含不在两个字符集中的字符。
在 MySQL 4.1 之前创建的老表中,如果非二进制列包含使用了与服务器默认字符集不同的字符集编码值,例如应用程序可能将 sjis 值存储在一个列中,而 MySQL 的默认字符集不同。可以将该列转换为正确的字符集,但需要额外步骤。假设服务器的默认字符集是 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 语句。如果已经修改过,MySQL 将使用 latin1 存储新值,该列将包含 sjis 和 latin1 值的混合,无法正确转换。
如果您在创建列时指定了属性,应该也在使用ALTER TABLE语句中指定它们。例如,如果您指定了NOT NULL和明确的DEFAULT值,应该在ALTER TABLE语句中提供它们。否则,结果列定义不包括这些属性。
要将表中的所有字符列转换为指定的字符集,可以使用ALTER TABLE ... CONVERT TO CHARACTER SET 语句。见第15.1.9节,“ALTER TABLE 语句”。charset