除了普通的INSERT外,mysql还多了一个REPLACE,关于他网上的帖子太多了,基本上这么开头:
在向表中插入数据的时候,经常遇到这样的情况:1. 首先判断数据是否存在; 2. 如果不存在,则插入;3.如果存在,则更新。
其实个人觉得REPLACE这个功能很鸡肋,很多人都会用错,今天我同事就用错了,毁了我一片数据,还好量很微小,这也引发我写个这个帖子的原因。
很多人理解replace into语句跟我同事类似:无则insert,有则update;其实不是这样的,而是:无则insert,有则delete,insert
对于数据表test:
- CREATE TABLE IF NOT EXISTS `test` (
- `id` int(10) NOT NULL,
- `username` char(64) NOT NULL,
- `telephone` char(11) NOT NULL,
`add` char(11) NOT NULL,
- PRIMARY KEY (`username`)
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
- INSERT INTO `test` (`id`, `username`, `telephone`, `add`) VALUES
- (1, 'eno', '13888888888' ,'test');
现在我想修改用户名为eno的电话号码,如果没有就插入,很多人想到用replace,然后就写:
- replace into test(username,telephone) values ('eno', '12345678910');
这样一写就得悲催了!
运行前:
- mysql> select * from test;
- +----+----------+-------------+------+
- | id | username | telephone | add |
- +----+----------+-------------+------+
- | 1 | eno | 13888888888 | test |
- +----+----------+-------------+------+
- 1 row in set (0.00 sec)
运行后:
- mysql> replace into test(username,telephone) values ('eno', '12345678910');
- Query OK, 2 (关键点 两条语句被改变) rows affected, 2 warnings (0.00 sec)
- mysql> select * from test;
- +----+----------+-------------+-----+
- | id | username | telephone | add |
- +----+----------+-------------+-----+
- | 0 | eno | 12345678910 | |
- +----+----------+-------------+-----+
- 1 row in set (0.00 sec)
结果是add和id的值也没有了,要想使用replace的插入更新,则必须是所有字段都得replace,而对于想“特定字段无则插入有则插入”replace表示无能为力,所以我觉得有点鸡肋。
特定字段无则插入有则插入的sql语句应该这么写:
- INSERT INTO `test` (`username`,`telephone`) values('eno','12345678910')
- ON DUPLICATE KEY UPDATE `telephone` = '12345678910';
mysql的延时插入的sql
- INSERT DELAYED INTO `test` (`id`, `username`, `telephone`, `add`) VALUES
- (1, 'eno', '13888888888' ,'test');
上面是个延时插入的sql,sql将在mysql空闲、一定时间、一定事件触发时异步写入硬盘,不保证数据的完整性,所以请大家谨慎使用。