最近在做一个阿里云跨账号的数据库迁移,这个库是和论坛相关的,用的是Discuz程序,数据库中有一张myisam表,用于记录帖子和楼层。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
mysql> show create table abc_ddxid_ppiy_gdsitnpl \G; *************************** 1. row *************************** Table: abc_ddxid_ppiy_gdsitnpl Create Table: CREATE TABLE `abc_ddxid_ppiy_gdsitnpl` ( `pid` int(10) unsigned NOT NULL, `fid` mediumint(8) unsigned NOT NULL DEFAULT '0', `tid` mediumint(8) unsigned NOT NULL DEFAULT '0', `first` tinyint(1) NOT NULL DEFAULT '0', `floorid` int(8) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`tid`,`floorid`), UNIQUE KEY `pid` (`pid`), KEY `fid` (`fid`), KEY `first` (`tid`,`first`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED |
这里可以看到tid是帖子号,floorid是楼层,这里用了一个myisam的复合索引第二列作为自增值,到的分组自增值的效果。
见mysql官方文档:3.6.9 Using AUTO_INCREMENT
对于分组自增值,在innodb和myisam的不同行为,可以用下面的测试过程演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
mysql> show variables like '%engine%'; +----------------------------+--------+ | Variable_name | Value | +----------------------------+--------+ | default_storage_engine | InnoDB | | default_tmp_storage_engine | InnoDB | | storage_engine | InnoDB | +----------------------------+--------+ 3 rows in set (0.00 sec) mysql> mysql> mysql> CREATE TABLE myisam_animals ( -> grp ENUM('fish','mammal','bird') NOT NULL, -> id MEDIUMINT NOT NULL AUTO_INCREMENT, -> name CHAR(30) NOT NULL, -> PRIMARY KEY (grp,id) -> ) ENGINE=MyISAM; Query OK, 0 rows affected, 2 warnings (0.00 sec) mysql> mysql> mysql> INSERT INTO myisam_animals (grp,name) VALUES -> ('mammal','dog'),('mammal','cat'), -> ('bird','penguin'),('fish','lax'),('mammal','whale'), -> ('bird','ostrich'); Query OK, 6 rows affected (0.01 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> mysql> mysql> SELECT * FROM myisam_animals ORDER BY grp,id; +--------+----+---------+ | grp | id | name | +--------+----+---------+ | fish | 1 | lax | | mammal | 1 | dog | | mammal | 2 | cat | | mammal | 3 | whale | | bird | 1 | penguin | | bird | 2 | ostrich | +--------+----+---------+ 6 rows in set (0.01 sec) mysql> mysql> mysql> mysql> mysql> mysql> mysql> mysql> CREATE TABLE innodb_animals ( -> grp ENUM('fish','mammal','bird') NOT NULL, -> id MEDIUMINT NOT NULL AUTO_INCREMENT, -> name CHAR(30) NOT NULL, -> PRIMARY KEY (id,grp) -> ) engine=innodb; Query OK, 0 rows affected (0.01 sec) mysql> mysql> INSERT INTO innodb_animals (grp,name) VALUES -> ('mammal','dog'),('mammal','cat'), -> ('bird','penguin'),('fish','lax'),('mammal','whale'), -> ('bird','ostrich'); Query OK, 6 rows affected (0.01 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> mysql> mysql> SELECT * FROM innodb_animals ORDER BY grp,id; +--------+----+---------+ | grp | id | name | +--------+----+---------+ | fish | 4 | lax | | mammal | 1 | dog | | mammal | 2 | cat | | mammal | 5 | whale | | bird | 3 | penguin | | bird | 6 | ostrich | +--------+----+---------+ 6 rows in set (0.00 sec) mysql> |
阿里云RDS关于MySQL数据库的myisam引擎的支持,规律如下:
(1)MySQL 5.6的版本
a)create table engine=myisam 且用到分组自增序列,那么不会进行转换。
b)create table engine=myisam 不用自增分组序列,那么内部进行转换,转成innodb
注,用dts迁移整个数据库,迁移之后,在目标库仍保持原状,innodb的表还是innodb的,利用了分组自增序列的myisam的表还是myisam的,原始表如果创建的时候,手动写myisam但是没有用到分组自增序列,那么在创建的时候,就自动转成innodb,因此dts迁移过去之后,也仍然是innodb。
(2)MySQL 5.7版本以上
已经不支持myisam,create table engine=myisam 报错,已经不能创建。
如果用的是innodb创建的,非分组的自增序列,需要实现分组自增功能,需要改造代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
mysql> SELECT (@I := CASE -> WHEN @GRP = GRP THEN -> @I + 1 -> ELSE -> 1 -> END) ROWNUM, -> innodb_animals.NAME, -> (@GRP := GRP) -> FROM innodb_animals, (SELECT @I := 0, @GRP := '') AS A -> GROUP BY GRP, ID; +--------+---------+---------------+ | ROWNUM | NAME | (@GRP := GRP) | +--------+---------+---------------+ | 1 | lax | fish | | 1 | dog | mammal | | 2 | cat | mammal | | 3 | whale | mammal | | 1 | penguin | bird | | 2 | ostrich | bird | +--------+---------+---------------+ 6 rows in set (0.00 sec) |