情况是这样的,生产环境上客户需求在一个表中添加一个description字段,方便客户知道这条记录具体是干啥的,我把线上备份的数据拉到本地,一看这个表有780538条记录,其中还有多个text类型的列,在本地试了试,常用命令内部基本都是copy一个临时表出来,然后修改表名,这种操作对于线上服务是不可行的,后来就上网找了找,发现了一个解决方案,我个人认为对于我们访问量不大的服务是可行的。
假设表结构如下:
CREATE TABLE `product` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`)
)
步骤如下
1. 创建product_new表结构与product一致
CREATE TABLE `product_new` LIKE `product`;
2. 删掉product_new上的索引
ALTER TABLE `product_new` DROP INDEX `name`;
3. 添加descrition到product_new
ALTER TABLE `product_new` ADD COLUMN `description` varchar(255) DEFAULT NULL AFTER `name`;
4. 插入旧数据
INSERT INTO `product_new`(`id`,`name`,`createdAt`,`updatedAt`) SELECT `id`,`name`,`createdAt`,`updatedAt` FROM `product`;
5. 获取product_new表中最大的id
SELECT MAX(id) INTO @maxidnew FROM `product_new`;
6. 从produt插入新数据到product_new
INSERT INTO `product_new`(`id`,`name`,`description`,`createdAt`,`updatedAt`) SELECT `id`,`name`,null,`createdAt`,`updatedAt` FROM `product`;
7. 重命名表名
ALTER TABLE `product` RENAME `product_old`;
ALTER TABLE `product_new` RENAME `product`;
8. 添加索引
ALTER TABLE `product` ADD INDEX `name`(`name`);
思考
-
这种方案只适合访问量不大的服务,访问量太大就不可行
-
操作过程需要注意,先确认mysql登录账号是否有相应的alter table权限,因为有的公司是有专人来管理数据库,我在操作过程中,幸好在alter table卡住了,没啥影响,线上操作还是要小心些
参考: