diff --git a/migrate-from-mariadb.md b/migrate-from-mariadb.md index d2afb4eb4e62..e1ce58a7e209 100644 --- a/migrate-from-mariadb.md +++ b/migrate-from-mariadb.md @@ -256,6 +256,84 @@ ORDER BY 更多信息,请参考[字符集和排序规则](/character-set-and-collation.md)。 +### 索引长度 + +如下例所示,在 MariaDB 中,如果索引长度超过最大键长度,MariaDB 会自动将该索引转换为前缀索引,并返回警告。与 MariaDB 不同,TiDB 遵循 MySQL 的行为,不会执行这种自动转换,而是直接返回错误。因此,在将 MariaDB DDL 迁移到 TiDB 时,如果索引列可能超过 TiDB 支持的最大键长度,你需要修改你的脚本,显式创建前缀索引。 + +``` +MariaDB> \W +Show warnings enabled. +MariaDB> CREATE TABLE t1(id SERIAL, c1 VARCHAR(800)); +Query OK, 0 rows affected (0.024 sec) + +MariaDB> ALTER TABLE t1 ADD INDEX(c1); +Query OK, 0 rows affected, 1 warning (0.031 sec) +Records: 0 Duplicates: 0 Warnings: 1 + +Note (Code 1071): Specified key was too long; max key length is 3072 bytes +MariaDB> SHOW CREATE TABLE t1\G +*************************** 1. row *************************** + Table: t1 +Create Table: CREATE TABLE `t1` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `c1` varchar(800) DEFAULT NULL, + UNIQUE KEY `id` (`id`), + KEY `c1` (`c1`(768)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +1 row in set (0.001 sec) +``` + +对于超过最大键长度的唯一索引,MariaDB 也会进行特殊处理。例如,在以下示例中,MariaDB 会为 `TEXT` 列创建 `USING HASH` 的唯一索引。TiDB 不提供此功能。 + +``` +MariaDB> CREATE TABLE t2 (id SERIAL PRIMARY KEY, c1 TEXT NOT NULL); +Query OK, 0 rows affected (0.015 sec) + +MariaDB> ALTER TABLE t2 ADD INDEX regular_index_c1 (c1); +Query OK, 0 rows affected, 1 warning (0.034 sec) +Records: 0 Duplicates: 0 Warnings: 1 + +Note (Code 1071): Specified key was too long; max key length is 3072 bytes +MariaDB> ALTER TABLE t2 ADD UNIQUE INDEX unique_index_c1 (c1); +Query OK, 0 rows affected (0.048 sec) +Records: 0 Duplicates: 0 Warnings: 0 + +MariaDB> SHOW CREATE TABLE t2\G +*************************** 1. row *************************** + Table: t2 +Create Table: CREATE TABLE `t2` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `c1` text NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unique_index_c1` (`c1`) USING HASH, + KEY `regular_index_c1` (`c1`(768)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +1 row in set (0.001 sec) +``` + +如需在 TiDB 中对长文本列进行唯一性约束,可以添加一个生成的哈希列,并在该生成的哈希列上创建唯一索引,如下所示: + +``` +tidb> CREATE TABLE t1 (id int PRIMARY KEY, c1 TEXT NOT NULL); +Query OK, 0 rows affected (0.102 sec) + +tidb> ALTER TABLE t1 ADD COLUMN c1_hash BINARY(32) AS (UNHEX(SHA2(c1,256))); +Query OK, 0 rows affected (0.242 sec) + +tidb> ALTER TABLE t1 ADD UNIQUE KEY (c1_hash); +Query OK, 0 rows affected (0.363 sec) + +tidb> INSERT INTO t1(id,c1) VALUES (1,'aaa'); +Query OK, 1 row affected (0.015 sec) + +tidb> INSERT INTO t1(id,c1) VALUES (2,'bbb'); +Query OK, 1 row affected (0.006 sec) + +tidb> INSERT INTO t1(id,c1) VALUES (3,'aaa'); +ERROR 1062 (23000): Duplicate entry '\x984\x87m\xCF\xB0\\xB1g\xA5\xC2IS\xEB\xA5\x8CJ\xC8\x9B\x1A\xDFW' for key 't1.c1_hash' +tidb> +``` + ## 使用 Dumpling 导出数据后使用 TiDB Lightning 导入 该迁移策略假定你将应用程序下线,迁移数据,然后重新配置应用程序以使用迁移后的数据。