4種插入數據的方式
第一種:insert into
insert into是最常用的插入數據的方式,可以單條插入,也可以多條,還可以指定從其他表中select然后插入。 詳細可以參考:insert語法參考。
第二種:insert ignore into
加上ignore,當表中有相同鍵的時候,忽略插入。因此從效果上來說,就是以舊數據為准。它和下面將要介紹的第三種插入方式正好相反。
第三種:replace into
使用replace,如果表中有沖突的鍵,那么先刪除這樣的行,然后插入。從效果上來說,就是以新數據為准。 前面的兩種方式,要么全舊,要么全新,那么有沒有折中的方式呢?這就是第四種:有選擇的替換。
第四種:insert into on duplicate key update
當發現沖突鍵的時候,有選擇的更新某些列的值。這里有個特別的values函數,當遇到數據沖突時,可以引用values中的值來更新相關的數據:INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
舉個例子,字段a被定義為UNIQUE,並且原數據庫表table中已存在記錄(2,2,9)和(3,2,1),如果插入記錄的a值與原有記錄重復,則更新原有記錄,否則插入新行:
INSERT INTO TABLE (a,b,c) VALUES
(1,2,3),
(2,5,7),
(3,3,6),
(4,8,2)
ON DUPLICATE KEY UPDATE b=VALUES(b);
以上SQL語句的執行,發現(2,5,7)中的a與原有記錄(2,2,9)發生唯一值沖突,則執行ON DUPLICATE KEY UPDATE,將原有記錄(2,2,9)更新成(2,5,9),將(3,2,1)更新成(3,3,1),插入新記錄(1,2,3)和(4,8,2)
注意:ON DUPLICATE KEY UPDATE只是MySQL的特有語法,並不是SQL標准語法!
使用場景
有了上面的介紹,使用場景已很明了。特別說明幾點:
-
如果表沒有主鍵,或主鍵是沒有意義的偽列,而且沒有其他唯一約束,那么請不要使用replace into,因為這種情況下使用insert into同樣可以做到,你畫蛇添足的效果可能就是像上面一樣,觸發bug。
-
如果表上有自增的主鍵,還有其他唯一鍵,那么使用replace into要小心了:其他唯一鍵一旦沖突,舊數據會被刪除,然后插入新的數據行,結果就是自增主鍵的值越來越大,盡管表的數據量不大。長此以往,即使表的數據只有區區幾千行,但是自增列的值可能非常大,最后越界。這種情況下可以采用insert into on duplicate key update的方式。當然也可以去掉自增的列,但是innodb的聚簇索引結構情況下,修改主鍵是”比較愚蠢的做法”。
-
關於返回值的判斷:一條replace into語句可能會影響多行。如果一個表有多個唯一鍵,如果發生鍵沖突,必須先刪除一行,再試圖插入數據的時候,可能與第二個唯一鍵又沖突,又需要刪除…,因此有可能刪除了多行數據最后才成功插入一條數據。因此,被刪除的行數是受影響的行數減1。
-