最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

insert...on?duplicate?key?update語法詳解

 更新時間:2023年01月09日 10:51:12   作者:ZhaoYingChao88  
本文主要介紹了insert...on?duplicate?key?update語法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一.作用和使用場景

在mysql入庫時,不能出現兩條數據主鍵一致的情況,因為在兩條數據的主鍵一致的情況下,mysql就會判定為待插入數據在數據庫中存在重復數據,也就是說判斷數據是否重復是根據主鍵來區(qū)別的。

但是有一些場景,如日志文件解析入庫,消息隊列接收數據入庫等情況下可能解析到或者接收到待插入的重復數據存在重復數據則更新不存在則插入。

這時如下語句的寫法就派上用場了,on duplicate key update的作用也就是說存在重復數據則更新,不存在則插入。

二.例子詳細講解

場景大概是這樣的,業(yè)務方的需求是查詢一條語句在不在,如果在就給出一個update語句,更新這條記錄,如果不在,就給出一個insert語句,插入這條記錄。邏輯大概是:

result =  select * from table;
if result = 0
   insert the record into table;
else
   update the record;

這樣的操作乍一看沒有什么問題,但是仔細分析分析,還是有些瓶頸的,目前來看,我能分析到的瓶頸有兩個,

其一:

每次要執(zhí)行2個SQL,效率比較差;

其二:

當我們在高并發(fā)的情況下跑這條語句,如果程序崩潰,不能保證操作的原子性。

說明:
1. on duplicate key update 含義:
  1)如果在INSERT語句末尾指定了 on duplicate key update,
      并且插入行后會導致在一個UNIQUE索引或PRIMARY KEY中出現重復值,
      則在出現重復值的行執(zhí)行UPDATE;
  2)如果不會導致唯一值列重復的問題,則插入新行。
 
2. values(col_name)函數只是取當前插入語句中的插入值,并沒有累加功能。
  如:count = values(count) 取前面 insert into 中的 count 值,并更新
        當有多條記錄沖突,需要插入時,前面的更新值都被最后一條記錄覆蓋,
        所以呈現出取最后一條更新的現象。
  如:count = count + values(count) 依然取前面 insert into 中的 count 值,
        并與原記錄值相加后更新回數據庫,這樣,當多條記錄沖突需要插入時,
        就實現了不斷累加更新的現象。
 
注:insert into ... on duplicate key update ... values() 這個語句
    盡管在沖突時執(zhí)行了更新,并沒有插入,但是發(fā)現依然會占用 id 序號(自增),
    出現很多丟失的 id 值,可參看下面案例

 函數使用說明:在一個 INSERT … ON DUPLICATE KEY UPDATE … 語句中,你可以在 UPDATE 子句中使用 VALUES(col_name ) 函數,用來訪問來自該語句的 INSERT 部分的列值。換言之,UPDATE 子句中的 VALUES(col_name ) 訪問需要被插入的 col_name 的值 , 并不會發(fā)生重復鍵沖突。這個函數在多行插入中特別有用。 VALUES() 函數只在 INSERT ... UPDATE 語句中有意義,而在其它情況下只會返回 NULL。

**案例:
0. 創(chuàng)建案例表 word_count_0626(單詞計數表)
  use test;
  CREATE TABLE IF NOT EXISTS word_count_0626 (
  	id int(11) NOT NULL AUTO_INCREMENT,
  	word varchar(64) NOT NULL,
  	count int(11) DEFAULT 0,
  	date date NOT NULL,
  	PRIMARY KEY (id),
  	UNIQUE KEY word (word, date)  // (word,date) 兩字段組合唯一
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  
注:curdate() 為 "2019-06-26"
1. 執(zhí)行第一次:(首次數據庫表中沒有數據,正常插入)
  insert into word_count_0626 (word, count, date) values 
  ('a',5,curdate()) 
  on duplicate key update count=values(count);
  # 結果顯示:
  id   word    count    date 
  1    a       5        2019-06-26
  
2. 執(zhí)行第二次:(與第一次的唯一(word,date)沖突,執(zhí)行更新)
  insert into word_count_0626 (word, count, date) values 
  ('a',6,curdate()) 
  on duplicate key update count=values(count);
  # 結果顯示:
  id   word    count    date 
  1    a       6        2019-06-26  (更新)
  
3. 執(zhí)行第三次:
  insert into word_count_0626 (word, count, date) values 
  ('a',6,curdate()-1),    // 取前一天,不會沖突
  ('a',7,curdate()) // 沖突
  on duplicate key update count=values(count);
  # 結果顯示:
  id   word    count    date 
  1    a       7        2019-06-26  (更新)
  3    a       6        2019-06-25  (新插入)
  
4. 執(zhí)行第四次:(更新沖突的最后一條插入值)
  insert into word_count_0626 (word, count, date) values 
  ('a',2,curdate()),  // 沖突
  ('a',1,curdate())  // 沖突
  on duplicate key update count=values(count);
  # 結果顯示:
  id   word    count    date 
  1    a       1        2019-06-26  (更新最后一條插入值)
  3    a       6        2019-06-25  (不變)
  
5. 執(zhí)行第五次:(更新沖突的累加插入值)
  insert into word_count_0626 (word, count, date) values 
  ('a',2,curdate()),
  ('a',1,curdate()) 
  on duplicate key update count=count+values(count); // 實現每行累加
  # 結果顯示:
  id   word    count    date 
  1    a       4        2019-06-26
  3    a       6        2019-06-25
 
6. 執(zhí)行第六次:(無沖突插入,觀察 id 鍵值,出現了很多丟失,id 直接跳到了 9)
  insert into word_count_0626 (word, count, date) values 
  ('b',2,curdate())
  on duplicate key update count=count+values(count);
  # 結果顯示:
  id   word    count    date 
  1    a       4        2019-06-26
  3    a       6        2019-06-25
  9    b       2        2019-06-26

說明:

insert...on duplicate key方法

簡單寫一個例子,內容大致如下:

1、首先創(chuàng)建一個包含id,name,age的表,其中id是主鍵;

2、在這個表中插入一條id=1的記錄;

3、使用insert...on duplicate key update語法插入一條id=2的記錄;

4、使用同樣的語法更新id=1的記錄;

mysql 23:12:32>>create table test_1( 
    -> id int primary key auto_increment,
    -> name varchar(20),
    -> age int not null
    -> ) engine=innodb charset=utf8;
Query OK, 0 rows affected (0.08 sec)
 
mysql 23:13:26>>insert into test_1 values (1,'yyz',16);
Query OK, 1 row affected (0.01 sec)
 
mysql 23:13:58>>select * from test_1;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | yyz  |  16 |
+----+------+-----+
1 row in set (0.00 sec)
 
 
mysql 23:14:36>>insert into test_1 (id,name,age) values (2,'yyz',18) on duplicate key update age=18;
Query OK, 1 row affected (0.01 sec)
 
mysql 23:15:08>>select * from test_1;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | yyz  |  16 |
|  2 | yyz  |  18 |
+----+------+-----+
2 rows in set (0.00 sec)
 
mysql 23:15:17>>insert into test_1 (id,name,age) values (1,'yyz',18) on duplicate key update age=18;
Query OK, 2 rows affected (0.00 sec)
 
mysql 23:15:28>>select * from test_1;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | yyz  |  18 |
|  2 | yyz  |  18 |
+----+------+-----+
2 rows in set (0.00 sec)

insert...on duplicate key update語法的作用,可以分析到,當發(fā)生主鍵沖突的時候,可以直接進行update操作,這個update操作里面可以更新任意想要更新的列;而沒有主鍵沖突的時候,相當于對這個表進行了一次插入操作。

Replace操作

Replace語句。使用Replace插入一條記錄時,如果不重復,Replace就和Insert的功能一樣,如果有重復記錄,Replace就使用新記錄的值來替換原來的記錄值。

使用REPLACE的最大好處就是可以將Delete和Insert合二為一,形成一個原子操作。這樣就可以不必考慮在同時使用Delete和Insert時添加事務等復雜操作了。

在使用Replace時,表中必須有唯一索引,而且這個索引所在的字段不能允許空值,否則Replace就和Insert完全一樣的。

在執(zhí)行Replace后,系統(tǒng)返回了所影響的行數,如果返回1,說明在表中并沒有重復的記錄,如果返回2,說明有一條重復記錄,系統(tǒng)自動先調用了Delete刪除這條記錄,然后再記錄用Insert來插入這條記錄。

不同之處

有了上面的知識儲備,這兩條命令的不同之處就顯而易見了,replace是刪除記錄,然后再重新insert,而insert...on duplicate key update是直接在該條記錄上修改,所以二者的差別主要有以下兩處:

1、當表中存在自增值的時候,如果表中存在某條記錄,replace語法會導致自增值+1,而insert...on duplicate key update語法不會;

2、當表中的某些字段中包含默認值的時候,replace操作插入不完全字段的記錄,會導致其他字段直接使用默認值,而insert...on duplicate key update操作會保留該條記錄的原有值。

到此這篇關于insert...on duplicate key update語法詳解的文章就介紹到這了,更多相關insert...on duplicate key update 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 教你用eclipse連接mysql數據庫

    教你用eclipse連接mysql數據庫

    這篇文章主要介紹了教你用eclipse連接mysql數據庫,文中有非常詳細的圖文示例,對不會鏈接mysql的小伙伴們有很大的幫助,需要的朋友可以參考下
    2021-04-04
  • MySQL 分區(qū)與分庫分表策略應用小結

    MySQL 分區(qū)與分庫分表策略應用小結

    在大數據量、復雜查詢和高并發(fā)的應用場景下,單一數據庫往往難以滿足性能和擴展性的要求,本文將詳細介紹這兩種策略的基本概念、實現方法及優(yōu)缺點,并通過實際案例展示如何在項目中應用它們,感興趣的朋友一起看看吧
    2025-04-04
  • MySQL基本操作語句小結

    MySQL基本操作語句小結

    這篇文章主要介紹了MySQL的基本操作語句,是MySQL入門學習中的基礎知識,需要的朋友可以參考下
    2015-07-07
  • mysql臟頁是什么

    mysql臟頁是什么

    本文主要介紹了什么是mysql臟頁,為什么會出現臟頁,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • MySQL中使用distinct單、多字段去重方法

    MySQL中使用distinct單、多字段去重方法

    多個字段拼接去重是指將多個字段的值按照一定的規(guī)則進行拼接,并去除重復的拼接結果,本文主要介紹了MySQL中使用distinct單、多字段去重方法,感興趣的可以了解一下
    2024-05-05
  • mysql 表維護與改造代碼分享

    mysql 表維護與改造代碼分享

    當數據庫中表的數量比較多時,不利于維護,本文將以此問題進行詳細介紹如何維護mysql表,與如何修改mysql表
    2012-11-11
  • win7下MySql 5.7安裝配置方法圖文教程

    win7下MySql 5.7安裝配置方法圖文教程

    這篇文章主要為大家分享了win7下MySql 5.7安裝配置方法圖文教程,感興趣的小伙伴們可以參考一下
    2016-05-05
  • 淺析MySQL - MVCC

    淺析MySQL - MVCC

    這篇文章主要介紹了MySQL - MVCC的相關資料,幫助大家更好的理解和使用MySQL數據庫,感興趣的朋友可以了解下
    2020-11-11
  • MySQL數據庫?JDBC?編程(Java?連接?MySQL)

    MySQL數據庫?JDBC?編程(Java?連接?MySQL)

    這篇文章主要介紹了MySQL數據庫?JDBC?編程Java?連接?MySQL,在?Java?中,這樣的封裝就是由?Java?標準庫來完成的,封裝出了一套統(tǒng)一的數據庫?API?稱為?JDBC,下面來看文章的詳細介紹吧
    2021-12-12
  • 淺談MySQL中的子查詢優(yōu)化技巧

    淺談MySQL中的子查詢優(yōu)化技巧

    這篇文章主要介紹了淺談MySQL中的子查詢優(yōu)化技巧,子查詢的優(yōu)化是MySQL諸多優(yōu)化方法中的基本,需要的朋友可以參考下
    2015-05-05

最新評論

瑞金市| 临澧县| 易门县| 龙山县| 勃利县| 常山县| 台北市| 武胜县| 永年县| 乐至县| 建宁县| 安龙县| 名山县| 丰原市| 扶沟县| 瑞安市| 汕头市| 延边| 扎鲁特旗| 弋阳县| 汝城县| 丘北县| 大荔县| 邢台市| 麦盖提县| 铁力市| 阿巴嘎旗| 齐齐哈尔市| 乳山市| 永康市| 泊头市| 瓮安县| 赫章县| 龙南县| 秦安县| 香格里拉县| 新巴尔虎左旗| 新巴尔虎左旗| 赤峰市| 博白县| 澄城县|