整理以下:mysql
表示插入數據,數據庫會檢查主鍵(Primary-Key)和惟一索引(Unique-Index),若是出現重複會出現相似如下報錯:sql
INSERT INTO table_name (column1, column2, column3) VALUES (1,2,3); ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
表示,若是表中已經存在相同的數據記錄(如主鍵和惟一索引),則忽略當前新數據,不進行插入或更新操做,也不報錯,只插入不相同的新數據。數據庫
INSERT IGNORE INTO table_name (column1, column2, column3) VALUES (1,2,3); Query OK, 0 rows affected (0.00 sec)
表示插入或替換數據。spa
1, 若是目標表中有Primary-Key,或者Unique索引的話,當出現相同值時,則用新數據替換舊數據。code
注意這裏的替換,它包含兩個意思:索引
1.1, 原數據行將被物理刪除,從而生成一條新行;table
1.2, REPLACE語句中含有的字段,原數據行的該字段的值將被新數據值替換,而對於語句中未含有的表中的其餘字段,它們的舊數據值被刪除後,若是這些字段都有默認值,則會被更新爲默認值,若是有任何一個字段沒有默認值,則會報錯。class
從這兩個角度來看,REPLACE INTO語句是存在風險的。test
ERROR 1364 (HY000): Field 'column1' doesn't have a default value
2, 若是沒有則和INSERT INTO同樣插入數據;擴展
3, REPLACE INTO 語句會返回一個數,來指示受影響的行的數目。該數是被刪除和被插入的行數的和。
REPLACE INTO table_name (column1, column2, column3) VALUES (1,2,3); Query OK, 2 rows affected (0.00 sec)
對於一條只操做一行記錄的REPLACE INTO語句來講,
若是它的受影響數爲1,則表示新行被插入,同時沒有舊行被刪除,等同於INSERT INTO。
若是該數大於1,則在新行被插入前,有一個或多個舊記錄行被刪除。
若是表包含多個惟一索引,而且新行復制了在不一樣的惟一索引中的不一樣舊行的值,則有多是一個單一行替換了多箇舊行。
表示若是和已存在的主鍵或惟一鍵(二者都有或者有多個的話會依次進行檢查),有任何一個相同,則按照UPDATE後的語句對原數據行進行更新。若是都不存在,則進行插入操做。
其實這個是本來須要執行3條SQL語句(SELECT,INSERT,UPDATE),縮減爲1條語句。
即
IF (SELECT * FROM where 存在) { UPDATE SET WHERE ; } else { INSERT INTO; }
如
INSERT INTO table_name(column1, column2, column3) VALUES (1,2,3) ON DUPLICATE KEY UPDATE column3 = 4; Query OK, 2 rows affected (0.00 sec)
上面語句用僞代碼表示即爲
if (select * from table_name where column1=1) { update table_name set column3 = 4 where column1=1 } else { insert into table_name(column1,column2,column3) values (1,2,3) }
和REPLACE INTO同樣,這個語句返回的受影響行數也是被刪除和被插入的行數的和,可是它的刪除是對舊歷史數據版本的刪除。
例如:
//建立表 mysql> CREATE TABLE test( -> id INT NOT NULL AUTO_INCREMENT, -> col1 VARCHAR(32) NOT NULL, -> col2 VARCHAR(32) DEFAULT NULL, -> PRIMARY KEY(id), -> UNIQUE KEY(col1) -> ); Query OK, 0 rows affected (0.46 sec) //插入數據 mysql> insert into test (id, col1, col2) VALUES (null,'unique','123456'); Query OK, 1 row affected (0.04 sec) mysql> select * from test; +----+--------+--------+ | id | col1 | col2 | +----+--------+--------+ | 1 | unique | 123456 | +----+--------+--------+ 1 row in set (0.00 sec) //執行操做 mysql> insert into test (id, col1, col2) values(null, 'unique', '654321') on duplicate key update col1 = 'update_unique'; Query OK, 2 rows affected (0.03 sec) //結果 mysql> select * from test; +----+---------------+--------+ | id | col1 | col2 | +----+---------------+--------+ | 1 | update_unique | 123456 | +----+---------------+--------+ 1 row in set (0.00 sec)
能夠看到,操做返回2條記錄受影響.可是主鍵ID並未改變,只有惟一鍵受到影響.
若是更新多個字段能夠像下面這樣寫
INSERT INTO table_name(column1, column2, column3) VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE column2=3, column3 = 4;
擴展閱讀: UPDATE操做必定是先DELETE再INSERT嗎?