一个MySQL的alter convert的案例
最近在做生产和测试表结构巡检的时候发现的这个case。
这里复现并记录下,
代码语言:sql复制[test] > select @@sql_mode;
+------------+
| @@sql_mode |
+------------+
| |
+------------+
[test] > CREATE TABLE `sbt1` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`policy_id` bigint(20) unsigned NOT NULL COMMENT '',
`content` text NOT NULL COMMENT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb3;
使用alter convert将字符集改为utf8mb4的
[test] > ALTER TABLE sbt1 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
再次查看表结构,发现content列的类型变成了mediumtext了
[test] > show create table sbt1 \G
*************************** 1. row ***************************
Table: sbt1
Create Table: CREATE TABLE `sbt1` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`policy_id` bigint unsigned NOT NULL,
`content` mediumtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
上面的这个case, 如果是sql_mode是严格模式的话,也是一样的效果。
但是下面的这个case,在sql_mode不同的时候,结果就不太一样了。
代码语言:sql复制create database test2;
use test2;
[test2] > show variables like '%sql_mode%' \G
*************************** 1. row ***************************
Variable_name: sql_mode
Value: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
1 row in set (0.01 sec)
[test2] > CREATE TABLE `sbt2` (
-> `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
-> `policy_id` bigint(20) unsigned NOT NULL COMMENT '',
-> `content` varchar(60000) NOT NULL COMMENT '',
-> PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb3;
ERROR 1074 (42000): Column length too big for column 'content' (max = 21845); use BLOB or TEXT instead
content太长了,调低点,如下:
[test2] > CREATE TABLE `sbt2` (
-> `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
-> `policy_id` bigint(20) unsigned NOT NULL COMMENT '',
-> `content` varchar(21810) NOT NULL COMMENT '',
-> PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb3;
Query OK, 0 rows affected, 3 warnings (0.03 sec)
执行convert,可以看到继续报错了
[test2] > ALTER TABLE sbt2 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ERROR 1074 (42000): Column length too big for column 'content' (max = 16383); use BLOB or TEXT instead
改下sql_mode为宽松模式后再试试
[test2] > set sql_mode='';
Query OK, 0 rows affected (0.00 sec)
可以看到convert执行成功了
[test2] > ALTER TABLE sbt2 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Query OK, 0 rows affected, 1 warning (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 1
但是有个warning,提示做了类型转换
[test2] > show warnings;
+-------+------+--------------------------------------------------+
| Level | Code | Message |
+-------+------+--------------------------------------------------+
| Note | 1246 | Converting column 'content' from VARCHAR to TEXT |
+-------+------+--------------------------------------------------+
1 row in set (0.00 sec)
[test2] > show create table sbt2 \G
*************************** 1. row ***************************
Table: sbt2
Create Table: CREATE TABLE `sbt2` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`policy_id` bigint unsigned NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)