MySql實現無則插入有則更新的解決方案

2021-08-28 13:30:18 字數 1832 閱讀 8231

某些場景會有這樣的需求:無記錄則插入,有記錄則更新。例如:新增使用者,以身份證號碼作為唯一身份標識,插入時若先查詢是否存在記錄再決定插入還是更新,在高併發情況下必然存在問題。本文提供三種解決方案。

無論通過synchronized鎖、reentranlock鎖還是分布式鎖,都可以解決該問題。缺點是,加鎖會影響效能。方法二和三都是資料庫層面解決方案,個人感覺比方法一好一些。

首先對唯一性的字段新增唯一索引alter table tb_name add unique (col1、col2...),,通過唯一索引即可保證資料的唯一性。

加入唯一索引後,通過insert into插入相同資料就會報錯,此時需要使用replace into插入資料,用法是一樣的。通過replace into插入資料時,若存在相同資料,會將之前的記錄刪除,再重新插入資料。缺點是,存在先刪除再插入的過程,sql需要考慮全部資料列,不然會丟失部分列的資料。缺點是,建立唯一索引會影響插入效率。下面是具體的例子。

# 建立索引

alter

table

user

addunique

(id_card)

;# 假設user表只有id,name,id_card三個字段,且id欄位自增。

# 現在需要插入name=ly,id_card=142733的記錄。

# 但是,若之前存在id_card=142733的記錄,修改name=ly即可。

replace

into

user

(id,name,id_card)

select id,

'ly'

,142733

from

user

right

join

(select1)

as tab

onuser

.id_card =

142733

;

通過right join (select 1),若存在id_card=142733的記錄,執行sql後會將原始id儲存在臨時的結果集中,隨name和id_card一同插入。若不存在該記錄,則將null作為id隨name和id_card一同插入。最終實現

通過預插入語句,嘗試插入,判斷修改的記錄是否大於0,若大於0表示插入成功,若為0則表示記錄已存在,需要執行更新操作。

# 預插入

insert

into

user

(name,id_card)

select

'ly'

,142733

from dual

where

not existe (

select id_card from

user

where id_card =

142733);

# 若預插入語句插入成功(修改記錄數=1),則無需後續操作。否則執行更新操作。

update

user

set name =

'ly'

where id_card =

142733

;

通過not existe條件,若存在id_card=142733的記錄則偽表dual記錄為空,預插入語句修改記錄為0,此時需要執行更新操作。若不存在id_card=142733的記錄,則偽表dual記錄為一行且內容是'ly',142733,預插入語句修改記錄為1,此時不必執行更新語句。

mybatis mysql 有則更新,無則插入

建立表 在這裡插入drop table if exists virtualmachines create table virtualmachines name varchar 100 not null comment 虛擬機器名稱 status varchar 100 default null co...

peewee 實現 有則更新,無則插入

在本地的資料庫測試了,以下是測試語句及結果 表結構class 測試 def upsert func rowid practice insert name aka male id 1 on conflict preserve practice.practice.name execute print r...

mysql有則更新 批量 mysql 批量更新

private function parseupdate data,field,table sql update set keys array keys current data print r keys die foreach keys as column 如何用一條sql語句實現批量更新?mys...