有坑勿踩(三)——关于数据更新

栏目: 数据库 · 发布时间: 5年前

内容简介:数据更新,CRUD中的U,对任何数据库而言都是最基本的操作。看似简单的更新操作中会藏着哪些坑?今天聊一聊这个话题。在写这个系列文章时,我会假设读者已经对MongoDB有了最基础的了解,因此一些基本名词和概念就不做过多的解释,请自己查阅相关资料。以shell为例,MongoDB的数据更新可以使用以下几种方式:

前言

数据更新,CRUD中的U,对任何数据库而言都是最基本的操作。看似简单的更新操作中会藏着哪些坑?今天聊一聊这个话题。

在写这个系列文章时,我会假设读者已经对 MongoDB 有了最基础的了解,因此一些基本名词和概念就不做过多的解释,请自己查阅相关资料。

数据更新方式

shell 为例,MongoDB的数据更新可以使用以下几种方式:

db.<collection>.update()
db.<collection>.updateMany()
db.<collection>.updateOne()
db.<collection>.save()
db.<collection>.findAndModify()

前三种是由于历史原因产生的,实际上:

  • updateMany = update + {multi: true}
  • updateOne = update 或 update + {multi: false}

因为 update 本身的意义不够清楚,所以3.0以后才出现了 updateManyupdateOne 两个替代方法。这个方法没多少要说的,唯一要注意的就是,如果用 update 方法的话,不要忘记操作符( $set , $inc 等等),不然……

updateManyupdateOne 则没有这个问题,缺了操作符会直接报错。

更新操作对比

update三兄弟和findAndModify

很多人的疑问可能都在这里,它们到底有什么区别,傻傻分不清楚。

首先参数不一样:

请阅读文档不多赘述。

其次功能不一样,

update 只是更新操作,而 findAndModify 可以在找到结果后选择执行更新还是删除操作。说白了功能上 findAndModify = updateOne + removeOne 。注意它只能对单个文档进行操作。

无论更新还是删除,(『找到』『更新』)或(『找到』『删除』)都是原子性的,这点 findAndModifyupdateOne / removeOne 没有任何区别。区别只在于 findAndModify 在完成动作之后还可以选择把更新/删除之前或之后的文档返回给你。如果没有这个操作,那就必须先 findupdate 或者先 updatefind ,无论怎么做,都不能保证中间不被其他操作捷足先登。因此 findAndModify 在某些场景下是必要的,比如使用 $inc 生成递增序列(注意生成递增序列做ID不是个好想法,我在这个问题中做过解释)

因为 findAndModify 只针对单个文档,那么如果条件能找到多个文档怎么办? sort 就用在这种场景下。

update和save

save 实际上是一种特殊的 update ,即不带操作符的 update 。通俗地说叫『替换』。替换,代表你已经有这个文档完整的样子,即代表你已经把整个文档从数据库中读出来,在内存中进行了修改,然后完整替换回去。你并不能保证数据在被你读出来到写回去期间是否有别人已经改了数据库中的记录,这就是第一个风险, save 操作存在潜在的可能性会覆盖掉别人更新过的数据。例如:

db.celebrity.findOne()
{
    _id: "孙悟空",
    title: "石猴"
    age: 500
}

你执行了:

var obj = db.celebrity.findOne({_id: "孙悟空"});
obj.title = "弼马温";
// 其他操作
db.celebrity.save(obj);

在『其他操作』的地方有人把孙悟空的 title 更新成了『齐天大圣』,很显然在你 save 的时候你会把它改回『弼马温』。

除了上述问题, save 还带来一个额外的副作用,因为整个文档都保存进去了,意味着整个文档都会进入oplog,这会显著增加oplog的使用速度。因此过度使用 save 常常还会造成oplog不够用,需要很大的oplog才能足够保存24小时的信息。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

编程珠玑(第二版)

编程珠玑(第二版)

[美] Jon Bentley / 谢君英、石朝江 / 中国电力出版社 / 2004-4 / 28.00元

《编程珠玑(第2版)》是计算机科学方面的经典名著。书的内容围绕程序设计人员面对的一系列实际问题展开。作者Jon Bentley 以其独有的洞察力和创造力,引导读者理解这些问题并学会解决方法,而这些正是程序员实际编程生涯中至关重要的。一起来看看 《编程珠玑(第二版)》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具