1. 程式人生 > >mysql處理存在則更新,不存在則插入(多列唯一索引)

mysql處理存在則更新,不存在則插入(多列唯一索引)

mysql處理某個唯一索引時存在則更新,不存在則插入的情況應該是很常見的,網上也有很多類似的文章,我今天就講講當這個唯一的索引是多列唯一索引時可能會遇到的問題和方法。

方法一:

使用 INSERT INTO ON ... DUPLICATE KEY UPDATE ... :

表的建立如下:

CREATE TABLE `test_table` (
  `id`  int(11) NOT NULL AUTO_INCREMENT ,
  `var1`  varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `var2`  tinyint(1) NOT NULL DEFAULT '0',
  `var3`  varchar(100) character set utf8 default NULL,
  `value1`  int(11) NOT NULL DEFAULT '1',
  `value2`  int(11) NULL DEFAULT NULL,
  `value3`  int(5) DEFAULT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE INDEX `index_var` (`var1`, `var2`, `var3`)
) ENGINE=MyISAM DEFAULT CHARACTER SET=latin1 AUTO_INCREMENT=1;

其中該表中var1、var2和var3完全相同的記錄只能有一條,所以建了一個多列唯一索引index_var,這樣一來我們就可以使用  INSERT INTO ON ... DUPLICATE KEY UPDATE ... 來實現插入資料時存在則更新,不存在則插入的功能了,如下:

INSERT INTO `test_table` 
(`var1`, `var2`, `var3`, `value1`, `value2`, `value3`) VALUES 
('abcd', 0, 'xyz', 1, 2, 3) 
ON DUPLICATE KEY UPDATE `value1` = `value1` + 1 AND 
`value2` = `value2` + 2 AND `value3` = `value3` + 3;

該條插入語句的含義是:向test_table表中插入,如果不存在val1 = 'abcd',val2 = 0, val3 = ‘xyz’的記錄,那就插入

val1 = 'abcd',val2 = 0, val3 = ‘xyz’,value1 = 1, value2 = 2, value3 = 3的記錄,

如果存在,那就更新value1的值為value1+1,更新value2的值為value2+2,更新value3的值為value3+3。

這樣,的確是沒有問題的,但是,如果表的建立如下:

CREATE TABLE `test_table` (
  `id`  int(11) NOT NULL AUTO_INCREMENT ,
  `var1`  varchar(1024) CHARACTER SET utf8 DEFAULT NULL,
  `var2`  tinyint(1) NOT NULL DEFAULT '0',
  `var3`  varchar(1024) character set utf8 default NULL,
  `value1`  int(11) NOT NULL DEFAULT '1',
  `value2`  int(11) NULL DEFAULT NULL,
  `value3`  int(5) DEFAULT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE INDEX `index_var` (`var1`, `var2`, `var3`)
) ENGINE=MyISAM DEFAULT CHARACTER SET=latin1 AUTO_INCREMENT=1;
注意:var1和var3的最大長度由100變成了1024,此時執行該建立語句時會報如下錯誤:
Specified key was too long; max key length is 1000 bytes
這是由於index_var索引的為1024 * 3 + 1 + 1024 * 3 > 1000導致的,如果遇到這種情況怎麼辦?有兩種解決辦法。

第一,將資料庫的engine由MyISAM換成InnoDB就可以了,那麼這兩個引擎有什麼區別呢?

看這裡

不過,這樣換有一個缺點,就是InnoDB的效能沒有MyISAM的好,那麼如果想要不犧牲效能的話,那就只有用第二個方法了,也就是我們這裡說的方法二!

方法二:

使用dual虛擬表來實現。

使用dual虛擬表來實現的話就不需要建立多列唯一索引了,表的建立如下:

CREATE TABLE `test_table` (
  `id`  int(11) NOT NULL AUTO_INCREMENT ,
  `var1`  varchar(1024) CHARACTER SET utf8 DEFAULT NULL,
  `var2`  tinyint(1) NOT NULL DEFAULT '0',
  `var3`  varchar(1024) character set utf8 default NULL,
  `value1`  int(11) NOT NULL DEFAULT '1',
  `value2`  int(11) NULL DEFAULT NULL,
  `value3`  int(5) DEFAULT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=MyISAM DEFAULT CHARACTER SET=latin1 AUTO_INCREMENT=1;
插入語句則是形如:
INSERT INTO table
(primarykey, field1, field2, ...)
SELECT key, value1, value2, ...
FROM dual
WHERE not exists (select * from table where primarykey = id);
的語句,此時我們可以用以下語句代替:
INSERT INTO `test_table` SELECT 0, 'abcd', 0, 'xyz', 1, 2, 3
FROM dual WHERE NOT EXISTS (
SELECT * FROM `test_table` WHERE 
`var1` = 'abcd' AND `var2` = 0 AND `var3` = 'xyz');
此時,如果val1 = 'abcd',val2 = 0, val3 = ‘xyz’的記錄不存在,那麼就會執行該插入語句插入該記錄,如果存在,那就需要我們再使用相應的更新語句來更新記錄:
UPDATE `test_table` SET 
`value1` = `value1` + 1, `value2` = `value2` + 2, `value3` = `value3` + 3
WHERE `val1` = 'abcd' AND `val2` = 0 AND `val3` = 'xyz';
OK!到這裡,基本上講完了。

注:轉載請註明出處!

參考:

博主所有文章已轉自私人部落格 Joe 的個人部落格,謝謝關注!

相關推薦

mysql處理存在更新存在插入唯一索引

mysql處理某個唯一索引時存在則更新,不存在則插入的情況應該是很常見的,網上也有很多類似的文章,我今天就講講當這個唯一的索引是多列唯一索引時可能會遇到的問題和方法。 方法一: 使用 INSERT INTO ON ... DUPLICATE KEY UPDATE ...

SQL Server與MySQL在“存在更新存在插入”併發處理上的一些差異。

“存在則更新,不存在則插入的邏輯”併發情況下的處理 在sqlserver中: 在sqlserver中,是通過可序列化隔離級別+排它鎖的方式來鎖定一個範圍來實現的當前鎖定一個不存在的記錄的時候,sqlserver是通過範圍鎖來實現的,具體鎖定的範圍,表中已存在的資料和當前具體判斷的Id有關參考之前寫的一

Mysql:如果資料存在更新存在插入

mysql語法支援如果資料存在則更新,不存在則插入,首先判斷資料存在還是不存在的那個欄位要設定成unique索引,例如表tb_addrbook如下:索引:語句1:不存在插入INSERT INTO tb_addrbook(num,name,mobile) VALUE('1001

MySQL insertOrUpdate 存在時更新存在時插入

前提:判斷更新或者插入的條件是 表裡的唯一索引是否衝突,比如插入主鍵值相同的資料。 如需要根據某個鍵值來判斷,必須建立唯一索引。 方式:使用 ON DUPLICATE KEY UPDATE 命令 Mybatis <insert id="insertOrUpdate

Oracle存在更新存在插入應用-merge

Oracle在9i引入了merge命令,通過這個merge你能夠在一個SQL語句中對一個表同時執行inserts和updates操作. 當然是update還是insert是依據於你的指定的條件判斷的,Merge into可以實現用B表來更新A表資料,如果A表中沒有,則把B表

oracle sql 記錄存在更新存在插入

MERGE <hint> INTO <table_name> USING <table_view_or_query> ON (<condition>) WHEN MATCHED THEN <update_clause&g

Mysql 存在既更新存在就新增sql語句

INSERT 語句的一部分,如果指定 ON DUPLICATE KEY UPDATE ,並且插入行後會導致在一個UNIQUE索引或PRIMARY KEY中出現重複值,則在出現重複值的行執行UPDATE,如果不會導致唯一值列重複的問題,則插入新行 sql 語句原型: i

MySql 存在記錄就更新存在就新增

1、插入一條資料,存在就更新,不存在就更新(必須現有唯一鍵)  使用insert ignore語句:insert ignore into table(col1,col2) values ('a','b');        例如插入資料:insert ignore i

mybatis 批量插入oracle 如果表裡存在就更新 存在就插入資料

判斷需要插入的資料是否存在,如果不存在就更新 <insert id="saveBatch" parameterType="java.util.List" >   MERGE INTO 表名 T   USING (  <foreach collection=

mysql有資料就更新沒資料就插入

原文連結:sql插入資料已經存在,則執行update更新-mysql教程-資料庫-壹聚教程網 http://www.111cn.net/database/mysql/76509.htm 在很多專案中,我們需要對資料進行不斷的呼叫和更新,如果有新的資料過來,還要把它加入到

MERGE--一個語句實現存在就更新存在就插入

使用MERGE語句從一個表中的選擇的行更新或插入到另一個表。是否更新或插入到目標表中的決定是基於在ON子句中的條件。它可以讓你避免多個INSERT和UPDATE DML語句。語法為: MERGE INTO table USING data_source ON (condition) WHEN MATCHED

MySQL 當記錄存在時插入insert if not exists

ron cli color 但是 應用 _id 記錄 需要 創建 在 MySQL 中,插入(insert)一條記錄很簡單,但是一些特殊應用,在插入記錄前,需要檢查這條記錄是否已經存在,只有當記錄不存在時才執行插入操作,本文介紹的就是這個問題的解決方案。 問題:我創建了一個

系統從SqlServer轉向Mysql儲存同時進行同步方案系統資料同步

業務系統底層儲存由原先SQLServer轉向Mysql,但由於歷史原因,SQLServer的資料庫與資料需要保留(原先業務的下游系統有很長資料庫同步鏈條),並需要實時與Mysql進行同步(單向同步)以下

mysql查詢是否存在某條記錄存在插入存在更新

在工作中,會遇到這樣的情形,查詢資料庫中是否存在一條記錄資訊,如果不存在則插入一條新的資訊,如果存在,則更新已有的資訊。 面對這樣的需求,之前採用的是先讀取一遍資料庫,判斷是否有資料,如果沒有則插入一條新資訊,如果有,則更新已有資訊,但是這種做法在高併發情況下可

【cmd】批處理:判斷檔案或目錄是否存在存在新建該檔案或目錄

目錄 一、通過複製方法建立檔案或目錄 二、通過新建方法建立檔案和目錄 一、通過複製方法建立檔案或目錄 (1)複製檔案(包括空檔案): @echo off echo result.jtl檔案判斷 SET SourceFile=G:\Jmeter\apache-jmete

MySQL插入資料時如果記錄存在insert如果存在update

MySQL 當記錄不存在時insert,當記錄存在時更新 網上基本有三種解決方法。 第一種: 示例一:insert多條記錄 假設有一個主鍵為 client_id 的 clients 表,可以使用下面的語句: INSERT INTO clients (clien

mysql ON DUPLICATE KEY UPDATE更新插入

1、適合用在需要 判斷記錄是否存在,不存在則插入存在則更新的場景  a 為 主鍵 或 擁有UNIQUE索引 INSERT INTO TABLE (a,c) VALUES (1,3),(1,8) ON DUPLICATE KEY UPDATE c=c+1;----c=4 INSE

MySQL新增資料存在就更新存在就新增

1、插入一條資料,存在則不操作,不存在就插入(必須現有唯一鍵) 使用insert ignore語句: insert ignore into table(col1,col2) values ('a','b'); 例如插入資料: insert ignore into use

MySQL新增數據存在就更新存在就添加

字段 執行 where into 插入 重復記錄 update 兩個 spa 1、插入一條數據,存在就更新,不存在就更新(必須現有唯一鍵)使用insert ignore語句: insert ignore into table(col1,col2) values (‘a

MySQL處理高並發防止庫存超賣

請求 新版 get 分離 upd 主鍵 sel 執行 實現 其實mysql處理高並發,防止庫存超賣的問題,在去年的時候,王總已經提過;但是很可惜,即使當時大家都聽懂了,但是在現實開發中,還是沒這方面的意識。今天就我的一些理解,整理一下這個問題,並希望以後這樣的課程能多點。