四種插入數據的MySQL語句比較

整理以下:mysql

  • INSERT INTO

表示插入數據,數據庫會檢查主鍵(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

表示,若是表中已經存在相同的數據記錄(如主鍵和惟一索引),則忽略當前新數據,不進行插入或更新操做,也不報錯,只插入不相同的新數據。數據庫

INSERT IGNORE INTO table_name (column1, column2, column3) VALUES (1,2,3);
Query OK, 0 rows affected (0.00 sec)
  • REPLACE INTO

表示插入或替換數據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,則在新行被插入前,有一個或多個舊記錄行被刪除。

若是表包含多個惟一索引,而且新行復制了在不一樣的惟一索引中的不一樣舊行的值,則有多是一個單一行替換了多箇舊行。

  • INSERT INTO ... ON DUPLICATE KEY UPDATE

表示若是和已存在的主鍵或惟一鍵(二者都有或者有多個的話會依次進行檢查),有任何一個相同,則按照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嗎?

相關文章
相關標籤/搜索