Skip to content

Commit d408703

Browse files
authored
migrate-from-mariadb: mention automatic prefix index (#22376)
1 parent 40d4e68 commit d408703

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

migrate-from-mariadb.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,84 @@ ORDER BY
256256

257257
See also [Character Set and Collation](/character-set-and-collation.md).
258258

259+
### Index length
260+
261+
As the following example shows, MariaDB automatically converts an index to a prefix index and returns a warning if the index exceeds the maximum key length. Unlike MariaDB, TiDB follows the MySQL behavior: it does not perform this automatic conversion and returns an error instead. Therefore, when migrating MariaDB DDL to TiDB, if an indexed column might exceed the maximum key length supported by TiDB, you need to modify your scripts to create a prefix index explicitly.
262+
263+
```
264+
MariaDB> \W
265+
Show warnings enabled.
266+
MariaDB> CREATE TABLE t1(id SERIAL, c1 VARCHAR(800));
267+
Query OK, 0 rows affected (0.024 sec)
268+
269+
MariaDB> ALTER TABLE t1 ADD INDEX(c1);
270+
Query OK, 0 rows affected, 1 warning (0.031 sec)
271+
Records: 0 Duplicates: 0 Warnings: 1
272+
273+
Note (Code 1071): Specified key was too long; max key length is 3072 bytes
274+
MariaDB> SHOW CREATE TABLE t1\G
275+
*************************** 1. row ***************************
276+
Table: t1
277+
Create Table: CREATE TABLE `t1` (
278+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
279+
`c1` varchar(800) DEFAULT NULL,
280+
UNIQUE KEY `id` (`id`),
281+
KEY `c1` (`c1`(768))
282+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
283+
1 row in set (0.001 sec)
284+
```
285+
286+
MariaDB also has special handling for unique indexes that exceed the maximum key length. For example, in the following example, MariaDB creates a `USING HASH` unique index on a `TEXT` column. TiDB does not provide this feature.
287+
288+
```
289+
MariaDB> CREATE TABLE t2 (id SERIAL PRIMARY KEY, c1 TEXT NOT NULL);
290+
Query OK, 0 rows affected (0.015 sec)
291+
292+
MariaDB> ALTER TABLE t2 ADD INDEX regular_index_c1 (c1);
293+
Query OK, 0 rows affected, 1 warning (0.034 sec)
294+
Records: 0 Duplicates: 0 Warnings: 1
295+
296+
Note (Code 1071): Specified key was too long; max key length is 3072 bytes
297+
MariaDB> ALTER TABLE t2 ADD UNIQUE INDEX unique_index_c1 (c1);
298+
Query OK, 0 rows affected (0.048 sec)
299+
Records: 0 Duplicates: 0 Warnings: 0
300+
301+
MariaDB> SHOW CREATE TABLE t2\G
302+
*************************** 1. row ***************************
303+
Table: t2
304+
Create Table: CREATE TABLE `t2` (
305+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
306+
`c1` text NOT NULL,
307+
PRIMARY KEY (`id`),
308+
UNIQUE KEY `unique_index_c1` (`c1`) USING HASH,
309+
KEY `regular_index_c1` (`c1`(768))
310+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
311+
1 row in set (0.001 sec)
312+
```
313+
314+
To enforce uniqueness on a long text column in TiDB, you can add a generated hash column and create a unique index on that generated hash column as follows:
315+
316+
```
317+
tidb> CREATE TABLE t1 (id int PRIMARY KEY, c1 TEXT NOT NULL);
318+
Query OK, 0 rows affected (0.102 sec)
319+
320+
tidb> ALTER TABLE t1 ADD COLUMN c1_hash BINARY(32) AS (UNHEX(SHA2(c1,256)));
321+
Query OK, 0 rows affected (0.242 sec)
322+
323+
tidb> ALTER TABLE t1 ADD UNIQUE KEY (c1_hash);
324+
Query OK, 0 rows affected (0.363 sec)
325+
326+
tidb> INSERT INTO t1(id,c1) VALUES (1,'aaa');
327+
Query OK, 1 row affected (0.015 sec)
328+
329+
tidb> INSERT INTO t1(id,c1) VALUES (2,'bbb');
330+
Query OK, 1 row affected (0.006 sec)
331+
332+
tidb> INSERT INTO t1(id,c1) VALUES (3,'aaa');
333+
ERROR 1062 (23000): Duplicate entry '\x984\x87m\xCF\xB0\\xB1g\xA5\xC2IS\xEB\xA5\x8CJ\xC8\x9B\x1A\xDFW' for key 't1.c1_hash'
334+
tidb>
335+
```
336+
259337
## Dump data with Dumpling and restore data with TiDB Lightning
260338

261339
This method assumes that you take your application offline, migrate the data, and then re-configure your application to use the migrated data.

0 commit comments

Comments
 (0)