2014年6月4日星期三

alter ignore table 的一次悲剧


增加一个字段:
ALTER TABLE `appinfo` ADD `user_id_56` VARCHAR(30) NOT NULL AFTER `user_id`;
mysql> select user_id_56 from appinfo limit 10;
+------------+
| user_id_56 |
+------------+
|            |
|            |
|            |
|            |
|            |
|            |
|            |
|            |
|            |
|            |
+------------+
10 rows in set (0.00 sec)

设置这个字段唯一:
mysql> ALTER TABLE  `appinfo` ADD UNIQUE (`user_id_56`);
ERROR 1062 (23000): Duplicate entry '' for key 'user_id_56'

mysql> set session old_alter_table=1; 
Query OK, 0 rows affected (0.00 sec)

再次 alter :
mysql> ALTER ignore TABLE  `appinfo` ADD UNIQUE (`user_id_56`);
Query OK, 3807 rows affected (0.28 sec)
Records: 3807  Duplicates: 3806  Warnings: 0

看到 duplicates 为 3806,结果悲了个剧,数据去哪了,就剩下一条记录

mysql> select user_id_56 from appinfo limit 10;
+------------+
| user_id_56 |
+------------+
|            |
+------------+
1 row in set (0.00 sec)

mysql> 

还好有个备份的旧数据可以用,挽回。

加一个非空的唯一字段正确做法原本可以这样
ALTER TABLE `appinfo` ADD `user_id_56` VARCHAR(30) UNQIUE COMMENT '绑定的56user_id' AFTER `user_id`;

直接把 unqiue 放到 add 中,旧的数据默认就是 NULL 了,随便拿一个来测试看看:

mysql@test> select * from c;
+----+
| id |
+----+
|  9 |
| 10 |
+----+
2 rows in set (0.00 sec)

mysql@test> ALTER TABLE c ADD `user_id_56` VARCHAR(30) UNIQUE  COMMENT 'test' AFTER id ;
Query OK, 2 rows affected (0.01 sec)               
Records: 2  Duplicates: 0  Warnings: 0

mysql@test> select * from c;
+----+------------+
| id | user_id_56 |
+----+------------+
|  9 | NULL       |
| 10 | NULL       |
+----+------------+
2 rows in set (0.00 sec)

并不是 delete 和 truncate 或者 drop 才可以丢数据,其它情况的 db 的操作仍然需要谨慎。

没有评论:

发表评论