目录
2 Mongodb CRUD 操作
mongodb提供了创建,读取,修改,删除简称CRUD
2.1 Mongodb CRUD简介
mongodb存储的文档是和json格式类似的,但是mongodb存储的是BSON也就是,以2进制方式保存JSON格式数据。在mongodb中文档相当于记录,而存文档的Collection相当于表。
2.1.1数据库操作
查询
Mongodb可以对一个collection通过条件来过滤文档,并且可以用projection选择输出
数据修改
创建,更新,删除数据,只能修改单个collection(不包含嵌入方式)
2.1.2 相关特性
索引
Mongodb可以顺序的表示,也可以强制唯一性保存,mongodb中索引也是用b树保存,
读偏好
读偏好主要是用在复制集群中,从哪个实例中读取。
写注意(write concern)
不同的写注意保证了不同的数据写入要求,级别越低写入越快,但是写入安全性越低
2.2 Mongodb CRUD概述
读操作:游标,查询优化,分布式查询
写操作:写注意,分布式写操作
2.2.1读操作
查询接口
Mongodb通过提供的接口db.collection.find()方法来查询数据,会返回一个游标
查询行为
1.所有的查询只能针对一个collection
2.可以通过limits,skips,sort来影响查询结果
3.用sort()来范围查询的顺序
4.update修改数据和select的条件语法一样
5.在aggregation(聚合)管道中,$match管道提供了对mongodb的访问
Projection
Projection用来限制输出那些字段,_id是默认输出的。
Projection行为
1._id会默认出现,除非显示设置
2.对于包含array的字段,提供了$elemMatch,$slice,$等操作符
3.对于聚合,使用$Project来处理
相关概念
游标
mongodb查询db.collection.find()返回一个游标,若没有分配给一个变量直接运行20次
游标行为对于游标默认不活动时间超过10分钟就会被销毁,当然可以指定noTimeout标记,来先限制等待。
游标隔离级别游标在有效期内是不隔离的,若有写入操作就会影响,可以使用快照模式来处理
游标Batch数据从mongodb到客户端是以batch的方式,batch的大小最大不超过最大BSON文档的大小,对于很多查询而言,第一个batch返回101个文档,或者1MB的大小,之后是4MB。
对于包含sort的查询但是没有索引,mongodb会导入到内存然后排序,会在第一个batch的时候返回所有的结果。用cursor.hasnext()和cursor.next()的组合来看有没有下一个batct,获取下一个batch
游标信息通过命令cursorInfo来获取游标的信息:1.打开的游标总数,2.当前使用的客户端游标大小,3.从服务重启来,超时的游标数。
优化查询
索引和其他数据库中的一样,减少了没必要数据的查询。
创建索引来支持查询使用db.collection.ensureIndex()来创建索引
索引的选择度某些查询操作时选择度很差,比如$nin,$ne,高选择度的才可以更好的使用索引,$regex 也是没有办法使用索引的。
覆盖查询覆盖查询的条件:1.所有的字段都是索引的一部分,2.所有返回的字段也在索引中
查询计划
Mongodb优化器处理查询,并根据索引选择一个最有效的索引,当collection的数据量被改变优化器会偶尔重建计划,可以使用explain()来查看执行计划。
查询优化
优化器创建计划的过程:1.通过不同的索引,并发的执行查询,2.记录负荷的结果到buffer中,3.当非排序的查询计划全部返回,或者顺序的执行计划全部返回,或者顺序的执行计划返回了超过了一个指标,那么会停止其他执行的计划并选择这个计划
计划重建
当发生以下事件,计划会被重建:1.超过1000个写入,2.重建索引,3.添加或者删除索引,4.服务进程重启
分布式查询
从Sharded集群中读,Sharded允许数据分区,并对应用程序透明,查询会通过路由到达相关的实例中,通过shard key若没有shard key,查询会分发到索引的shard实例中取执行。
从复制集群中读,在复制集群中使用读偏好,来决定从哪个实例中读取数据,读偏好设置有一下几个好处:1.减少延迟,2.提供读的带宽,3.备份作用,4.容灾切换。同时也要注意,主库和分库之间的延迟,分库不能代表当前主库的数据状态。
2.2.2写操作
和读一样写操作只能用在一个collection上。
创建
通过接口,db.collection.insert()在collection上创建一个文档,若update接口在有upset的标记下,也可以实现创建文档的功能。
插入的行为
如果你插入时,没有指定_id那么mongodb会分配一个,若指定了_id需要保持在collection中是唯一的。
更新
通过接口,db.collection.update()来实现更新操作,也可以用save
更新行为
update默认只对一行进行更新,若要对多行进行更新要使用multi选项,通没有指定类似set的参数,就会把所有影响的文档替换,当更新是,文档的大小超过了原先分配的大小,那么会重新分配空间,然后把文档放入,这样会导致,文档内的字段重排。
删除
删除通过接口,db.collection.delete()实现。
删除的行为
默认使用delete不太条件,会把所以的文档全部删除
写操作的隔离性
修改一个文档,可以支持原子性,但是对多个文档的修改就不支持原子性,尽管如此单还是可以使用隔离操作(isolaation_operator)。也可以通过人工方式实现2阶段提交,来保证隔离性。
相关概念
主要介绍一下内容,写注意(write concern),分布式写操作,写选项性能,大批量插入到mongodb,行留白。
写注意(write concern)
弱写注意,可能会导致一些错误,因为不需要等服务端返回写入成功,强写注意,client可以等待写入完成。db.runCommand( { getLastError: 1, w: 2 } )来配置。
写注意级别:忽略错误(Error Ingored),最低级的级别,mongodb不会通知写入操作完成,包含 发生错误,性能最佳,但是会影响写入数据的一致性和持久性,w:-1
不通知:mongodb不会通知写入成功或者失败,但是当发生错误是,还是会尽力接受和处理错误,可以发现由系统网络配置导致的网络错误。w:0
通知:可以取回一个写入操作信息,这个级别,允许客户端抓取网络,重复key等错误,w:1。mongodb默认使用这个级别,写注意默认使用无参数的getLastError,对于复制集群可以在getLastErrorDefaults中定义默认的写注意,若没有定义默认使用getLastError取通知.
日志:使用这个级别,只有在提交,写入日志后,服务才会通知写入操作,这样可以保证服务崩溃后数据库的恢复。使用这个操作要指定w:1,j:true
复制通知:使用这个级别可以保证,写操作写入到了复制集群,w:>1,在复制集群下,只要再设置j:true,主库就可以用日志写注意级别。
分布式写
在sharded集群中写:可以根据shard key来对分区插入数据,可以提高写入性能,若没有key,会被广播到所有的shard,若数据库只插入到一个key,那么可能照成单点性能问题。
在复制集中写:在复制集中写入,会被写入到primary上,然后记录在oplog或者log中,然后根据oplog分发到分库中,对于密集的写入操作会导致分库和主库之间严重的延迟,虽然可以通过写注意保证一致性,但是会造成写入性能问题
写操作性能
索引:和其他数据库一样,写操作会修改索引,会带来一些性能消耗。
文档增长:update 操作文档的空间时,会分配一个新空间,然后把文档复制进去,这样会加大update的时间,in-place比文档增长来的有效。
存储性能
硬件:很多元素和存储系统有关,影响着服务的性能,如,随机读写性能,磁盘cache,预读,RAID级别。
日志:mongodb使用顺序写方式来记录日志,日志提供了一致性和crash弹性,考虑一下方面来增加日志性能:1.使用独立的设备,2.若写注意级别为日志,mongodb通过减少提交间隔来减少写负荷,3.通过手动配置journalCommitInterval来减少提交间隔。
大数据量写入
使用insert方法:insert方法通过传入一个数组来执行大数据量写入。通过写注意的设置大数据量写入,可以显著的提高性能。并且通过ContinueOnError选项可以让批量插入有错误下还能完成。
在Shard集群中:ContinueOnError只在非分片中有效,这类大批量写入,对sharded集群来说会降低性能若要写入考虑一下方案:
预分配splits:大批量导入中,若collection是空的,那么只有一个spilt,当插入时 重新分配split导致性能问题所以要预先split
避免单调增长:可能大批量插入只针对一个sharded key,这样sharded的性能就没 有办法体现,如无法避免,可以考虑:1.二进制方式翻转shard key,2.key的前16位和 后16位互换。
行留白(Record Padding)
因为超出文档就会重新分配,为了避免这个问题,可以事先留白,减少重分配的可能性。
留白因子:可以使用db.collection.stats()查看当前的paddingFactor,留白的大小可以通过一个公式计算:padding size = (paddingfactor-1)*<document size>。留白并不能对每个文档做准确的设置,只能根据文档大小的平均数。留白的大小只能通过执行compact或者repairDatabase选项回收。
删除留白:可以通过compact,repairDatabase和初始化复制同步选项来移除,导出导入也可以。
行分配策略:为了更加有效的使用因为删除而空闲的空间,或者文档重新分配的空间,可以指定mongodb分配的行大小,大小为2的n次。