文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9MB
PDF (A4) - 40.0MB
手册页 (TGZ) - 258.5KB
手册页 (Zip) - 365.5KB
信息 (Gzip) - 4.0MB
信息 (Zip) - 4.0MB


12.7 列字符集转换

要将二进制或非二进制字符串列转换为使用特定的字符集,请使用 ALTER TABLE。要成功进行转换,必须满足以下条件之一

  • 如果列具有二进制数据类型(BINARY、VARBINARY、BLOB),则它包含的所有值都必须使用单一字符集(要将列转换到的字符集)进行编码。如果使用二进制列存储多个字符集的信息,则 MySQL 无法知道哪些值使用哪个字符集,并且无法正确转换数据。

  • 如果列具有非二进制数据类型(CHAR、VARCHAR、TEXT),则其内容应使用列字符集进行编码,而不是其他字符集。如果内容使用其他字符集进行编码,则可以先将列转换为使用二进制数据类型,然后再转换为具有所需字符集的非二进制列。

假设表 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 之前的旧表,其中非二进制列包含实际上使用与服务器默认字符集不同的字符集编码的值,则会出现一种特殊情况。例如,即使 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 等语句修改表。在这种情况下,MySQL 将使用 latin1 在列中存储新值,并且该列将包含 sjis 和 latin1 值的混合,并且无法正确转换。

如果在最初创建列时指定了属性,则在使用 ALTER TABLE 修改表时,也应指定这些属性。例如,如果指定了 NOT NULL 和显式 DEFAULT 值,则还应在 ALTER TABLE 语句中提供它们。否则,生成的列定义将不包含这些属性。

要转换表中的所有字符列,ALTER TABLE ... CONVERT TO CHARACTER SET charset 语句可能会有用。请参阅 第 15.1.9 节“ALTER TABLE 语句”。