除了普通的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空閒、一定時間、一定事件觸發時異步寫入硬盤,不保證數據的完整性,所以請大家謹慎使用。