大型翻車現(xiàn)場:如何實現(xiàn)記錄存在就更新,如果記錄不存在就插入
Hi,大家好!我是白日夢!下文以自導(dǎo)自演的方式,圍繞“如何實現(xiàn)記錄存在的話就更新,如果記錄不存在的話就插入。”展開本話題。看看你能抗到第幾問吧
歡迎關(guān)注!持續(xù)更新中~

Hi同學(xué),前面表現(xiàn)的不錯哦。關(guān)于MySQL的基礎(chǔ)掌握的還可以,現(xiàn)在有時間繼續(xù)嗎?
嗯,有時間!

這個專題還有好多文章沒寫完呢!掛了怎么往下寫?

那我們繼續(xù)面吧。出一道場景題:現(xiàn)在我的業(yè)務(wù)中有這樣的需求:如果目標(biāo)記錄存在的話我就更新它,如果記錄不存在的話我就插入。說說看你知道哪些實現(xiàn)方式吧!

這種方式。
// 偽代碼user=User.FindById(1)if user == null{user.Insert()}else{user.Update()}



嗯,還可以像下面這樣,我先嘗試更新,如果沒有這條記錄的話,更新函數(shù)返回的影響行數(shù)就是0。
于是我根據(jù)這個影響行數(shù)去判斷,當(dāng)影響行數(shù)為0時說明數(shù)據(jù)庫中沒有這條記錄。于是我就寫入。

通過這種方式和MySQL之間的網(wǎng)絡(luò)請求次數(shù)就有可能降低成1。
// 偽代碼effectRows=User.UpdateById(1)if effectRows >0 {user.Insert()}


我看未必吧!并且你這代碼存在安全隱患啊!
比如遇到這種情況:user實例中的信息和數(shù)據(jù)庫中的記錄完全一致。然后你拿著user中的信息去更新數(shù)據(jù)庫中的信息。實際上就沒有發(fā)生任何改變。
也就是說,你的代碼中的UpdateById(1)的返回值是0!

然后你的代碼進(jìn)入else中,很顯然id=1的行已經(jīng)存在了,你還執(zhí)行insert xxx id = 1,這肯定會報錯說:主鍵沖突啊!
我靠!大佬說的對啊!按你這么說,這確實是個風(fēng)險。即使每次去更新的時候攜帶上最新的時間戳也無法保證它一定不會進(jìn)入到else中!


嗯,對的。我們繼續(xù)這個話題,你還知道其他的實現(xiàn)方式嗎?我提示你一下:你有沒有使用過 insert ignore into 語句?
嗯嗯,使用過,insert ignore into的作用是:如果記錄存在了就忽略本次ignore本次插入。如果記錄不存在就寫入。

關(guān)于insert ignore into的實戰(zhàn)可以看這個示例
Step1:創(chuàng)建庫表

Step2:正常寫入一條數(shù)據(jù)

Step3:使用insert ignore 重復(fù)寫入和上一條SQL完全一種的數(shù)據(jù)

Step4:使用insert ignore寫入一條新的數(shù)據(jù),會發(fā)現(xiàn)可以寫入成功。

Step5:使用insert ignore寫入,測試一下如果想寫入的數(shù)據(jù)的id(唯一key)已經(jīng)在表中存在了,其他的非唯一鍵數(shù)據(jù)不一樣。你會發(fā)現(xiàn):也不能重復(fù)寫入



嗯,通過你的實驗可以看出:insert ignore into的功能是:如果數(shù)據(jù)已經(jīng)存在了就忽略本次寫入,如果數(shù)據(jù)不存在就insert。通過上面你做的實驗也可以看出它判斷是否可以寫入的標(biāo)準(zhǔn)是:唯一鍵不能重復(fù)。
只要你想寫入的數(shù)據(jù)和現(xiàn)有的唯一鍵沖突了,最終就不會將你的數(shù)據(jù)落庫。
嗯嗯,這么看來insert ignore into 并不能滿足我們的業(yè)務(wù)需求。不過我還了解 replace into。


嗯!那你說說這個replace 吧!
好
,replace into的作用是:如果數(shù)據(jù)已經(jīng)存在了我就更新。如果數(shù)據(jù)不存在就更寫入。
而判斷數(shù)據(jù)是否已經(jīng)存在的標(biāo)準(zhǔn)依然是:判斷唯一鍵是否重復(fù)。


嗯,繼續(xù)。
嗯嗯,可以看下面的這個例子:
Step1:如果數(shù)據(jù)不存在replace 可以將數(shù)據(jù)寫入進(jìn)去

Step2:如果數(shù)據(jù)存在replace 可以使用新數(shù)據(jù)替換舊數(shù)據(jù)。

而且這個替換還是全量替換:



嗯,很好,使用replace into 確實能做到一次網(wǎng)絡(luò)請求就實現(xiàn)我們的業(yè)務(wù)需求。
其實我還知道另一種實現(xiàn)方式:也可以通過一次網(wǎng)絡(luò)請求實現(xiàn)咱們的業(yè)務(wù)需求。


哦?你說說看!
使用 on duplicate key update也可以實現(xiàn),如果記錄存在就更新,如果記錄不存在就插入。

關(guān)于: on duplicate key update可以看這個例子:
Step1: 如果已經(jīng)存在了,就更新。

Step2:如果不存在就寫入

(上面兩圖中的ignore不影響)







小伙子可以的!整體感覺還不錯。
歡迎關(guān)注我
。不久會給你安排下一面
。
我沒有問題了,你有什么想問我的嗎?
感謝大佬
,點(diǎn)贊、在讀、打賞、轉(zhuǎn)發(fā)馬上安排上!

往期精彩文章:
誰會拒絕一臺Win11和MacOS無縫切換的MacBook呢?Parallels17極速體驗
使用AI在原神里自動釣魚,掃描Git倉庫泄露的密碼 【Github熱榜周刊第三期】
3分鐘搭建一個網(wǎng)站?騰訊云Serverless開發(fā)體驗
