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