跳到主要内容

列级字符集和字符序

每个"字符"列(即类型为 CHARVARCHARTEXT 类型或任何同义词的列)都有一个列字符集和一个列字符序。

指定列的字符集和字符序

CREATE TABLEALTER TABLE 语句具有用于指定列的字符集和字符序,语法如下:

CREATE TABLE table_name (
column_name {CHAR | VARCHAR | TEXT} (column_length)
[CHARACTER SET charset_name]
[COLLATE collation_name]
);

ALTER TABLE table_name MODIFY
col_name {CHAR | VARCHAR | TEXT} (column_length)
CHARACTER SET [=] charset_name
[COLLATE [=] collation_name]

示例如下:

CREATE TABLE t (
col1 VARCHAR(5)
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci);
Query OK, 0 rows affected (0.055 sec)

ALTER TABLE t MODIFY
col1 VARCHAR(5)
CHARACTER SET gbk
COLLATE gbk_chinese_ci;
Query OK, 0 rows affected (0.477 sec)

选择列的字符集和字符序

seekdb 通过以下方式选择列的字符集和字符序:

  • 如果同时指定了 CHARACTER SET charset_nameCOLLATE collation_name,则使用字符集 charset_name 和字符序 collation_name

  • 如果指定了 CHARACTER SET charset_name 但未指定 COLLATE,则使用字符集 charset_name 及其默认字符序。要查看每个字符集的默认字符序,请使用 SHOW CHARACTER SET 语句。

  • 如果指定了 COLLATE collation_name 但未指定 CHARACTER SET,则使用与 collation_name 关联的字符集和指定的字符序。

  • 如果既不指定 CHARACTER SET 也不指定 COLLATE,则使用表的字符集和字符序。

如果在各个列定义中未指定列字符集和字符序,则表的字符集和字符序将用作列定义的默认值。

此外,seekdb 设置列的 COLLATE 后直接 ORDER BY 即可按照所设置的字符序排列,也可以在 ORDER BY 后使用 COLLATE 设置相同字符集的不同字符序。

CREATE TABLE t(a VARCHAR(10) COLLATE gb18030_2022_radical_ci);
Query OK, 0 rows affected (0.066 sec)

INSERT INTO t VALUES('a'),('A'),('b'),('B');
Query OK, 4 rows affected (0.003 sec)
Records: 4 Duplicates: 0 Warnings: 0

SELECT a FROM t ORDER BY a;
+------+
| a |
+------+
| a |
| A |
| b |
| B |
+------+
4 rows in set (0.002 sec)

SELECT a FROM t ORDER BY a COLLATE gb18030_2022_chinese_cs;
+------+
| a |
+------+
| A |
| B |
| a |
| b |
+------+
4 rows in set (0.002 sec)

列字符集转换条件

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

  • 如果列具有二进制数据类型(BINARYVARBINARYBLOB),则它包含的所有值都必须使用单个字符集(即要将列转换为的字符集)进行编码。如果使用二进制列来存储多个字符集的信息,seekdb 无法知道哪些值使用哪个字符集,无法正确转换数据。

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