摘要:前言數(shù)據(jù)更新,中的,對(duì)任何數(shù)據(jù)庫(kù)而言都是最基本的操作。你并不能保證數(shù)據(jù)在被你讀出來到寫回去期間是否有別人已經(jīng)改了數(shù)據(jù)庫(kù)中的記錄,這就是第一個(gè)風(fēng)險(xiǎn),操作存在潛在的可能性會(huì)覆蓋掉別人更新過的數(shù)據(jù)。
前言
數(shù)據(jù)更新,CRUD中的U,對(duì)任何數(shù)據(jù)庫(kù)而言都是最基本的操作。看似簡(jiǎn)單的更新操作中會(huì)藏著哪些坑?今天聊一聊這個(gè)話題。
在寫這個(gè)系列文章時(shí),我會(huì)假設(shè)讀者已經(jīng)對(duì)MongoDB有了最基礎(chǔ)的了解,因此一些基本名詞和概念就不做過多的解釋,請(qǐng)自己查閱相關(guān)資料。
數(shù)據(jù)更新方式以shell為例,MongoDB的數(shù)據(jù)更新可以使用以下幾種方式:
db.
db.
db.
db.
db.
前三種是由于歷史原因產(chǎn)生的,實(shí)際上:
updateMany = update + {multi: true}
updateOne = update 或 update + {multi: false}
因?yàn)?b>update本身的意義不夠清楚,所以3.0以后才出現(xiàn)了updateMany和updateOne兩個(gè)替代方法。這個(gè)方法沒多少要說的,唯一要注意的就是,如果用update方法的話,不要忘記操作符($set, $inc等等),不然……
updateMany和updateOne則沒有這個(gè)問題,缺了操作符會(huì)直接報(bào)錯(cuò)。
很多人的疑問可能都在這里,它們到底有什么區(qū)別,傻傻分不清楚。
首先參數(shù)不一樣:
findAndModify
update
請(qǐng)閱讀文檔不多贅述。
其次功能不一樣,
update只是更新操作,而findAndModify可以在找到結(jié)果后選擇執(zhí)行更新還是刪除操作。說白了功能上findAndModify=updateOne+removeOne。注意它只能對(duì)單個(gè)文檔進(jìn)行操作。
無(wú)論更新還是刪除,(『找到』『更新』)或(『找到』『刪除』)都是原子性的,這點(diǎn)findAndModify和updateOne/removeOne沒有任何區(qū)別。區(qū)別只在于findAndModify在完成動(dòng)作之后還可以選擇把更新/刪除之前或之后的文檔返回給你。如果沒有這個(gè)操作,那就必須先find再update或者先update再find,無(wú)論怎么做,都不能保證中間不被其他操作捷足先登。因此findAndModify在某些場(chǎng)景下是必要的,比如使用$inc生成遞增序列(注意生成遞增序列做ID不是個(gè)好想法,我在這個(gè)問題中做過解釋)
因?yàn)?b>findAndModify只針對(duì)單個(gè)文檔,那么如果條件能找到多個(gè)文檔怎么辦?sort就用在這種場(chǎng)景下。
save實(shí)際上是一種特殊的update,即不帶操作符的update。通俗地說叫『替換』。替換,代表你已經(jīng)有這個(gè)文檔完整的樣子,即代表你已經(jīng)把整個(gè)文檔從數(shù)據(jù)庫(kù)中讀出來,在內(nèi)存中進(jìn)行了修改,然后完整替換回去。你并不能保證數(shù)據(jù)在被你讀出來到寫回去期間是否有別人已經(jīng)改了數(shù)據(jù)庫(kù)中的記錄,這就是第一個(gè)風(fēng)險(xiǎn),save操作存在潛在的可能性會(huì)覆蓋掉別人更新過的數(shù)據(jù)。例如:
db.celebrity.findOne() { _id: "孫悟空", title: "石猴" age: 500 }
你執(zhí)行了:
var obj = db.celebrity.findOne({_id: "孫悟空"}); obj.title = "弼馬溫"; // 其他操作 db.celebrity.save(obj);
在『其他操作』的地方有人把孫悟空的title更新成了『齊天大圣』,很顯然在你save的時(shí)候你會(huì)把它改回『弼馬溫』。
除了上述問題,save還帶來一個(gè)額外的副作用,因?yàn)檎麄€(gè)文檔都保存進(jìn)去了,意味著整個(gè)文檔都會(huì)進(jìn)入oplog,這會(huì)顯著增加oplog的使用速度。因此過度使用save常常還會(huì)造成oplog不夠用,需要很大的oplog才能足夠保存24小時(shí)的信息。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/19495.html
摘要:注意記住的作用始終是把集群中具有投票權(quán)的節(jié)點(diǎn)總數(shù)湊成奇數(shù)用,防止腦裂。其代表的意義是集群中必須有大多數(shù)節(jié)點(diǎn)收到并確認(rèn)了一個(gè)寫操作,這個(gè)寫操作才算成功。無(wú)論源或者目標(biāo)片中不能夠滿足大多數(shù)時(shí),遷移都會(huì)失敗。在有可能的情況下,應(yīng)盡量使用代替。 前言 在技術(shù)社區(qū)混了這么長(zhǎng)時(shí)間,因?yàn)橐恍┏R姷募夹g(shù)問題反復(fù)被問到,總是想寫寫文章把它們講清楚。無(wú)奈很多時(shí)候看似基礎(chǔ)的技術(shù)問題背后都隱藏著很深的原因,想...
摘要:本質(zhì)上所有查詢的數(shù)據(jù)都是從游標(biāo)來的。的作用是從游標(biāo)中提取一批數(shù)據(jù),具體提取多少則是由決定。同時(shí)注意我們已經(jīng)有了一個(gè)游標(biāo)。為了便于理解,我們下面還是稱之為游標(biāo)超時(shí)。 前言 聊一聊一個(gè)最基本的問題,游標(biāo)的使用。可能你從來沒有注意過它,但其實(shí)它在MongoDB的使用中是普遍存在的,也存在一些常見的坑需要引起我們的注意。 在寫這個(gè)系列文章時(shí),我會(huì)假設(shè)讀者已經(jīng)對(duì)MongoDB有了最基礎(chǔ)的了解,因...
摘要:但是,用獲取到的集合卻不是的。于是小伙們做起了實(shí)驗(yàn),大致發(fā)現(xiàn),如果對(duì)節(jié)點(diǎn)進(jìn)行刪除,那么是如果新增節(jié)點(diǎn)則不是。如果有新發(fā)現(xiàn)歡迎評(píng)論留言另一個(gè)值得注意的是關(guān)于和。從的文檔上籠統(tǒng)來說,所有集合都可以叫做,不過需要注意如下 在寫一個(gè)小組建的時(shí)候用到了document.querySelector,被小伙伴提醒說這個(gè)可能有坑,是啥呢?先來一篇MDN的文檔解解饞:戳我戳我戳我>>>>>>>NodeL...
摘要:需求背景環(huán)境版本開發(fā)規(guī)范公司后端開發(fā)規(guī)范有這么一點(diǎn)更新數(shù)據(jù)庫(kù)表中數(shù)據(jù)的時(shí)候,不允許先刪,然后批量插入需要將入?yún)⑴c表中數(shù)據(jù)比判斷,找出哪些是新插入,哪些需要更新,哪些是刪除的,然后再做對(duì)應(yīng)的數(shù)據(jù)操作需求我們有表如下當(dāng)商 ...
閱讀 2186·2023-04-25 19:06
閱讀 1385·2021-11-17 09:33
閱讀 1772·2019-08-30 15:53
閱讀 2595·2019-08-30 14:20
閱讀 3552·2019-08-29 12:58
閱讀 3546·2019-08-26 13:27
閱讀 512·2019-08-26 12:23
閱讀 492·2019-08-26 12:22