MongDB介绍

13和14获得年度数据库.https://db-engines.com/en/ranking

官方文档: https://docs.mongodb.com/manual/

简介

MongoDB是面向文档的数据库, 有区别与传统的RDBM, 是一个基于文档(BSON, Binary Json)存储的开源数据库系统, 其主要的大致特性如下:

  • 易用性: MongoDB的文档可以类比RDBMS的行, 通过在文档中嵌入文档, 数组来表达复杂的层次关系,类似编程思想的组合.

  • 易拓展: scale属性, 面对数据的增加, 多节点的存储拓展, 传统的RDBMS的一般自身没有面对海量数据的能力, 而mongodb其内部自身实现了集群的数据与请求的负载分配.(分片)

  • 功能丰富: 支持索引, 聚合, 特殊集合, 文件存储(GridFS), map/reduce, 不支持在分布式架构中性能不佳的join(不需要), 事务(4.0已经支持).

  • 性能卓越: 尽可能保留RDBMS功能的同时追求卓越的性能, 主要体现为cache内存, 动态填充, 预分配数据文件等等.

主要用途

  • 跟RDBMS一样, 可以做应用数据库, 4.0之后支持了ACID事务, 同时模型更加灵活, 因为是BSON格式, 与面向对象十分吻合

  • 海量数据平台, 可以横向扩展, 数据切片存储.

BSON与JSON对比

https://docs.mongodb.com/manual/reference/bson-types/

Bson是一种类Json的一种二进制形式的存储格式,类型比Json要丰富, 空间存储不占优势, 更快的查询速度, 操作简单, 在MongoDB的大小限制是16mb, 每一个document都需要一个_id.

版本进展

  • 2008: 0.x: 起步阶段

  • 2010: 1.x: 支持复制集和分片集.

  • 2012: 2.x: 更丰富的数据库功能, 索引, 聚合等等

  • 2014: 3.x: 真正成熟, 有了自己的数据库引擎

  • 2018: 4.x: 支持了事务.

基础知识

主要有文档, 集合, 数据库, 键id, js shell.

  • 文档: 数据的基本单元, 可以理解为RDBMS的行, 是键值对的有序集, 组织结构类似json, 区别在于mongodb的文档字段是有顺序的.

  • 集合: 数据集合,可以理解为RDBMS的表, 但是集合是动态模式, 内部的文档可以是不同结构的, 但是出于索引的考虑, 最好将同一种结构的文档放到一个集合内, 自行设计相应模式.

比如设计父子结构: blog.posts, blog.authors, 其中blog这个父集合甚至不需要存在, 父子集合可以进行逻辑&物理上的分隔, 十分有用.

  • 数据库: 多个集合组成数据库, 每一个mongodb实例可以有多个数据库, 每个数据库的权限相互独立.

保留数据库: admin, local, config. 集合的完全限定名是cms.blog.posts, 其中cms是数据库的名字.

  • shell:mongo命令即可, 是一个js shell,可以运行简单的数学运算, 以及简单的插入查询,是mongodb客户端.

插入:db.blog.insert({x:5}) 查询: db.blog.findOne(),或者find(). 更新:db.blog.update(...) 删除:db.blog.remove(...)

  • 数据类型: (BSON)基本等同于json, 额外支持一些, 比如日期{"x":new Date()}, 比如对象id{"_id":ObjectId("...")}..etc

ObjectId在集合内唯一标志文档的id,11位int值, 使用不需要管, 会自动生成_id的key, 值的话跟时间戳,机器, pid以及计数器有关的hash值.

> db.blog.insert({x:1})
WriteResult({ "nInserted" : 1 })

db.blog.find()
{ "_id" : ObjectId("5e81c27c40ba929757681642"), "x" : 1 }

db和集合的增删

db不用创建, 直接use,或者insert数据后show dbs就能看到了

# 删除db
db.dropDatabase()

创建集合options是一个json配置, json Schema

db.createCollection(name, options)

删除集合

db.collection.drop()

json schema是无模式下的规范, https://docs.mongodb.com/manual/reference/operator/query/jsonSchema/

基本操作CRUD

具体语言的操作去看开头的官方文档.

create

insertOne/insertMany/insert

read

find/findOne

  • 简单查询条件: https://www.runoob.com/mongodb/mongodb-query.html

  • 正则匹配支持: db.col.find({title:/^教/}), 以教开头.

  • $type匹配: 匹配key的类型筛选出来.

  • $exist可以判断是否有某个key的筛选,

  • nin则是不连续的范围筛选.

  • 如果只需要返回文档的部分key, 就可以使用0,1来额外标志,find({"name":"huijia"},{"_id":0,"age":1}), 只返回age

  • pretty()相当于mysql \G, 美观显示.

  • limit(int)来限制返回的文档数目

  • 还有skip(int)来跳过指定数量的文档, 默认是0, 可以理解位offset.

  • 还有explain()来进行查询分析.

  • 使用hit({"x":1})来强制使用一个索引, 一般配合explain()使用.

update

主要通过操作符, 第一个参数是find的条件,第二个参数是操作.

db.users.update({"name":"huija"},{"$set":{"xxx":1}})

  • 其中$set是个修改器,

  • 还有$unset删除某个字段,

  • 还有$inc原子增加某个数值,

  • each给数组append数组, 配合sort, 指定权重, 排序后得到前面指定数量的元素.

  • push类似, 但是会进行去重后才会插入数组.

  • $ne是查询的时候, 指定不重复的字段.(相当于mysql group by limit 1)

  • $pop可以指定key,1表示从数组结尾删,-1表示从数组开头删.

  • $pull可以删除数组内全部匹配的元素值.

  • or可以进行查询条件约束, 其余可以百度..(太多), json子字段用'.'拼接

  • 支持正则匹配.

delete

deleteOne/deleteMany

还有个remove, 过时了,可以使用, 不会释放db的空间, 需要db.repairDatabase()来回收.

简单实践

# 增加

db.users.insert({"name":"huija","friends":32,"enemies":2})
WriteResult({ "nInserted" : 1 })

改update

db.users.find()
{ "_id" : ObjectId("5e82abb48c7542360d1e5434"), "name" : "huija", "friends" : 32, "enemies" : 2 }
var me=db.users.findOne({"name":"huija"})
me.relationships={"friends":me.friends,"enemies":me.enemies}
{ "friends" : 32, "enemies" : 2 }
delete me.friends
true
delete me.enemies
true
db.users.update({"name":"huija"},me)

查find,findOne

db.users.find({"name":"huija"})
{ "_id" : ObjectId("5e82abb48c7542360d1e5434"), "name" : "huija", "relationships" : { "friends" : 32, "enemies" : 2 } }

删remove,drop

db.users.drop()
true

但是上面的update,基本是整体覆盖, 如果想要针对单个属性,进行原子更新, 可以通过修改器实现.

updateOne, updateMany可以控制update的文档数目(1个或者多个)

_id最好不要自己设置

https://www.jianshu.com/p/9e582b470810 https://www.runoob.com/mongodb/mongodb-objectid.html

  • 相比较MySQL,MongoDB数据库更适合那些读作业较重的任务模型。MongoDB能充分利用机器的内存资源。如果机器的内存资源丰富的话,MongoDB的查询效率会快很多。

  • 在带”id”插入数据的时候,MongoDB的插入效率其实并不高。如果想充分利用MongoDB性能的话,推荐采取不带”id”的插入方式,然后对相关字段作索引来查询。

索引

创建很简单:db.col.createIndex({"title":1,"description":-1})

其中1表示升序, -1表示降序.

https://www.runoob.com/mongodb/mongodb-indexing.html

索引是B树, 需要全部加载进内存.

https://www.runoob.com/mongodb/mongodb-indexing-limitations.html

覆盖索引

mysql的覆盖索引主要是为了不回表, 在mongodb中也是类似, 我们可以 通过指定需要查询的值来达到目的.

db.users.find({gender:"M"},{user_name:1,_id:0})

其中1表示需要查出user_name, 0表示忽略默认就返回的_id.

mongodb还支持数组等各种子文档的索引

TTL索引

可以用于删除过期数据, ttl索引只支持在Date()类型单字段建立

当你在集合中某一个字段建立TTL索引后,后台会有一个单线程,通过不断查询(默认60s一次)索引的值来判断document是否有过期,
并且删除文档的动作还依据mongod实例的负载情况,如果负载很高,可能会稍微延后一段时间再删除。
还有一个需要注意的地方,在复制集成员中,TTL后台线程只删除primary的过期数据,如果此实例变为secondary角色,则后台线程闲置

https://blog.csdn.net/leshami/article/details/61195427

聚合

是一个pipeline处理, 指定一些聚合的组合,每一个聚合都是一个stage步骤, 整体作为参数进行聚合操作. db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

https://www.runoob.com/mongodb/mongodb-aggregate.html

聚合框架中常用的几个操作:

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。(as)

  • match使用MongoDB的标准查询操作。(where)

  • $limit:用来限制MongoDB聚合管道返回的文档数。

  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。

  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。

  • $group:将集合中的文档分组,可用于统计结果。(group by)

  • $sort:将输入文档排序后输出。(order by)

  • $geoNear:输出接近某一地理位置的有序文档。

  • $lookup: ... (left outer join)

引用

对于Bson的类型, 我们可以类比结构体, 而结构体是可以嵌套组合的, 而Bson如何实现文档的组合呢, 比较Bson是无范式的, 是很灵活的.

使用ObjectID, 类似地址一样, 进行组合.

{
"_id":ObjectId("52ffc33cd85242f436000001"),
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Benzamin",
"address_ids": [
ObjectId("52ffc4a5d85242602e000000"),
ObjectId("52ffc4a5d85242602e000001")
]
}

但是这只是文档的直接引用, 如果需要从多个db集合进行引用也是可以的, 具体需要指定一些额外参数.

优势

  • 易于开发者使用, 使用对象模式, 不需要特别多的时间进行建模, 而且不需要维护复杂的关系.

  • 可动态增加新字段, 但是也有一定的规则限制,Json Scheme.

  • 原生的高可用与横向拓展: 副本集, 一主两从, 数据冗余存储, 提高了数据的可用性, 并可以保证数据的安全性。https://www.runoob.com/mongodb/mongodb-replication.html

  • 另一种集群: 数据负载存储,可自定义分片规则.https://www.runoob.com/mongodb/mongodb-sharding.html . https://cloud.tencent.com/developer/article/1453249

  • 副本集可以与分片相结合: https://docs.mongodb.com/manual/tutorial/convert-replica-set-to-replicated-shard-cluster/

工具

  • mongodb提供了免费的云集群搭建.

  • 图形化软件, 官网提供了compass. https://www.mongodb.com/download-center/compass

  • demo数据集: https://raw.githubusercontent.com/tapdata/geektime-mongodb-course/master/aggregation/dump.tar.gz ,可以使用mongorestore来恢复, 默认当前目录下的mock文件夹, 备份恢复参考: https://www.runoob.com/mongodb/mongodb-mongodump-mongorestore.html

compass可以查看数据, 聚合计算, schema分析, 索引查看, 图形化explain, 制定一些schema约束(哪些key必须有, 哪些key的类型限定等等)

选型总结

如果业务满足一个或多个特点,那么选择MongoDB是个正确的决定:

  • 无需要跨文档或跨表的事务及复杂的join查询支持

  • 敏捷迭代的业务,需求变动频繁,数据模型无法确定

  • 存储的数据格式灵活,不固定,或属于半结构化数据

  • 业务并发访问量大,需数千的QPS

  • TB级以上的海量数据存储,且数据量不断增加

  • 要求存储的数据持久化、不丢失

  • 需要99.999%的数据高可用性

  • 需要大量的地理位置查询、文本查询

你可能感兴趣的:(MongDB介绍)