禁止修改varchar到int|[运维规范]

在MySQL更改数据类型前一定要特别小心,分析一下是不是可行,另外在更改前,需要先进行备份,备份,备份!!!

环境描述

表结构:

CREATE TABLE `t_mobile` (
 `mobile_no` varchar(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

写入数据:

root@zhishutang:mysql3306.sock [zst]>insert into t_mobile(mobile_no) values('13501245755'),('18800108001'),('13996000001');

确认数据无误:

root@zhishutang:mysql3306.sock [zst]>select * from t_mobile;
+-------------+
| mobile_no |
+-------------+
| 13501245755 |
| 18800108001 |
| 13996000001 |
+-------------+
3 rows in set (0.00 sec)

溢出

修改数类型:

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

查看警告:

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)

到这里实质就可以宣布,死定了。数据已溢出。

查看数据:

root@zhishutang:mysql3306.sock [zst]>select * from t_mobile;
+------------+
| mobile_no |
+------------+
| 2147483647 |
| 2147483647 |
| 2147483647 |
+------------+
3 rows in set (0.00 sec)

这里真是的男人哭吧,哭吧, … 如果是线上环境,想死的心估计大家都有了,不是简单的哭了。如果没有备份,这么重要一例数据没了,有可能意为着项目也有可能受到严重的影响。

这时也不要心存幻想在改回去就好,来看一下操作,请死心!!!

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”;”}

大概这样生成。 在执行恢复即可。

 

作者:吴炳锡 来源:http://wubx.net/ 联系方式: wubingxi#163.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

禁止修改varchar到int|[运维规范]》上有6个想法

  1. xtrdb.net [test]> select version();
    +————+
    | version() |
    +————+
    | 5.7.18-log |
    +————+
    1 row in set (0.00 sec)

    xtrdb.net [test]> alter table t_mobile change mobile_no mobile_no int;
    ERROR 1264 (22003): Out of range value for column ‘mobile_no’ at row 1

    • mysql> select version();
      +————+
      | version() |
      +————+
      | 5.6.31-log |
      +————+
      1 row in set (0.00 sec)
      mysql> alter table t_mobile change mobile_no mobile_no int;
      Query OK, 3 rows affected, 3 warnings (0.02 sec)

      ^_^

评论已关闭。