前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >有坑勿踩(三)——关于数据更新

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

作者头像
MongoDB中文社区
发布2019-03-21 16:29:05
4280
发布2019-03-21 16:29:05
举报
文章被收录于专栏:MongoDB中文社区MongoDB中文社区

前言

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

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

数据更新方式

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

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

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

更新操作对比

update三兄弟和findAndModify

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

请阅读文档不多赘述。

其次功能不一样, update只是更新操作,而findAndModify可以在找到结果后选择执行更新还是删除操作。说白了功能上findAndModify=updateOne+removeOne。注意它只能对单个文档进行操作。 无论更新还是删除,(『找到』『更新』)或(『找到』『删除』)都是原子性的,这点findAndModify和updateOne/removeOne没有任何区别。区别只在于findAndModify在完成动作之后还可以选择把更新/删除之前或之后的文档返回给你。如果没有这个操作,那就必须先find再update或者先update再find,无论怎么做,都不能保证中间不被其他操作捷足先登。因此findAndModify在某些场景下是必要的,比如使用$inc生成递增序列(注意生成递增序列做ID不是个好想法,我在这个问题中做过解释) 因为findAndModify只针对单个文档,那么如果条件能找到多个文档怎么办?sort就用在这种场景下。

update和save

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

你执行了:

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

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

关于作者

作者:张耀星

MongoDB大中华区首席咨询顾问MongoDB中文社区联席主席

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Mongoing中文社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档