在MySQL更改数据类型前一定要特别小心,分析一下是不是可行,另外在更改前,需要先进行备份,备份,备份!!!
一、环境描述
表结构:
1 2 3 4 |
CREATE TABLE `t_mobile` ( `mobile_no` varchar(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
写入数据:
1 2 |
root@zhishutang:mysql3306.sock [zst]>insert into t_mobile(mobile_no) values('13501245755'),('18800108001'),('13996000001'); |
确认数据无误:
1 2 3 4 5 6 7 8 9 10 |
root@zhishutang:mysql3306.sock [zst]>select * from t_mobile; +-------------+ | mobile_no | +-------------+ | 13501245755 | | 18800108001 | | 13996000001 | +-------------+ 3 rows in set (0.00 sec) |
二、溢出
修改数类型:
1 2 3 4 |
root@zhishutang:mysql3306.sock [zst]>alter table t_mobile change mobile_no mobile_no int; Query OK, 3 rows affected, 3 warnings (0.02 sec) Records: 3 Duplicates: 0 Warnings: 3 |
查看警告:
1 2 3 4 5 6 7 8 9 10 |
root@zhishutang:mysql3306.sock [zst]>show warnings; +---------+------+----------------------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------------------+ | Warning | 1264 | Out of range value for column 'mobile_no' at row 1 | | Warning | 1264 | Out of range value for column 'mobile_no' at row 2 | | Warning | 1264 | Out of range value for column 'mobile_no' at row 3 | +---------+------+----------------------------------------------------+ 3 rows in set (0.00 sec) |
到这里实质就可以宣布,死定了。数据已溢出。
查看数据:
1 2 3 4 5 6 7 8 9 10 |
root@zhishutang:mysql3306.sock [zst]>select * from t_mobile; +------------+ | mobile_no | +------------+ | 2147483647 | | 2147483647 | | 2147483647 | +------------+ 3 rows in set (0.00 sec) |
这里真是的男人哭吧,哭吧, … 如果是线上环境,想死的心估计大家都有了,不是简单的哭了。如果没有备份,这么重要一例数据没了,有可能意为着项目也有可能受到严重的影响。
这时也不要心存幻想在改回去就好,来看一下操作,请死心!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
root@zhishutang:mysql3306.sock [zst]>alter table t_mobile change mobile_no mobile_no varchar(11); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 root@zhishutang:mysql3306.sock [zst]>select * from t_mobile; +------------+ | mobile_no | +------------+ | 2147483647 | | 2147483647 | | 2147483647 | +------------+ 3 rows in set (0.00 sec) |
三、结论
- 生产环境更数据类型明确提出: 不允许varchar 改成int.
-
更改数据前一定要做好备份,无论是update,delete,或是数据类型更改。
四、操作Tips: 如保备份一列数据?
select pk , 修改的列 from tb where 条件 ;
用命令行记录也可以,用outfile处理也行。
恢复可以用awk反向生成update语句: cat bak.txt |awk ‘{print “update tb set 修改列名=“ $2,”where pk=”$1″;”}
大概这样生成,再执行恢复即可。