Mongo
官方文档:https://docs.mongodb.com
Mongo简介
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
版本
偶数版本为稳定版本,技术版本为开发版
NoSQL
Not Only SQL,意为不仅仅为SQL。现代计算机系统每天网络上都会产生庞大的数据量。这些数据很大部分由关系型数据库管理系统(RDBMS)处理。1970年 E.F.Codd's提出的关系模型的论文 "A relational model of data for large shared data banks",这使得数据建模和应用程序编程更加简单。
通过应用实践证明,关系模型是非常适合于客户服务器编程,远远超出预期的利益,今天它是结构化数据存储在网络和商务应用的主导技术。
NoSQL通常用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
RDBMs VS NoSQL
RDBMs | NoSQL |
---|---|
高度组织化、结构化的数据 | 非结构化和不可预知的数据 |
结构化查询语言(SQL) | 没有声明性的查询语言 |
数据与关系都存储在表中 | k-v存储,列存储,文档存储,图形存储 |
严格的一致性,ACID | 最终一致性,非ACID属性 |
具有事务 | 大部分没有事务 |
高性能,高可用性和可伸缩性 |
NoSQL的优缺点
优点 | 缺点 |
---|---|
高扩展性,架构灵活,半结构化数据 | 没有标准化 |
分布式计算 | 有限的查询功能(到目前为止) |
低成本 | 一致性较差 |
NoSQL数据库分类
存储方式 | 代表 | 特点 |
---|---|---|
xml数据库 | Berkeley DB XML,BaseX | 高效存储xml数据,并支持xml内部查询语法,比如XQuery,Xpath |
key-value存储 | Redis、MemcacheDB、Tokyo Cabine | 可以通过key快速查询到对应的value。一般情况下value可以存储任何格式(redis做了拓展)。 |
对象存储 | db4o、Versant | 通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。 |
文档存储 | MongoDB、CouchDB | 文档存储一般用类似JSON的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能 |
图存储 | Neo4J、FlockDB | 图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便 |
列存储 | Hbase、Cassandra、Hypertable | 按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势 |
适用场景
适用场景
网站实时数据
数据缓存
大尺寸、低价值的数据存储:如网盘
高伸缩性场景
文档JSON数据存储
不适用场景
高度事务性系统,比如银行以及会计系统
需要复杂的查询SQL
相关概念
MongoDB将数据存储为一个文档(document
),并以键值(k-v
)结构组成。MongoDB文档格式类似JSON,但是是以二进制形式存储,故称为BSON。
关于MongoDB中的属于概念:
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
安装MongoDB
docker安装
客户端工具
官方命令行工具
以下工具都位于 MongoDB的bin目录下,皆是可执行文件。
命令 | 作用 |
---|---|
| 服务端程序,用于启动MongoDB |
| 客户端程序,连接MongoDB,可执行 |
|
|
| 数据导入导出程序,支持CSV、JSON |
| 数据备份程序/数据恢复程序,将导出BSON格式,用于定期备份 |
| 数据分片程序,支持数据的横向扩展 |
| 监视程序,查看MongoDB 实时的增删改查操作的 pqs、以及内存使用、网络吞吐的信息 |
| 实时查看 MongoDB 在哪些集合上花的读写时间最多,能快速找出实例里的热点集合 |
| 抓包工具,直接下载二进制包可能并不包含这个工具,需要下载源码编译出来, |
| 测试磁盘 IO 性能的工具 |
客户端Driver
Mongo支持10+种语言的客户端,点我看官方文档。所有官方客户端driver都支持MongoDB Connection String URI的方式去连接。
mongodb 的连接串 uri
连接串格式为:
mongodb://
协议user:password@
可选的用户名与密码host1
至少指定一个host,代表mongodb服务端的地址portx
端口号,可选,缺省值为27017
/database
如果制定了username:password@
,将会连接登录指定的数据库。如果未指定,则会打开test数据库?options
可选项,如果未指定database
,加入此参数时,需要在尾部加入/
,多个options中,需要使用&
或者;
连接。
options的可用选项:
选项 | 描述 |
---|---|
replicaSet=name | 验证replica set的名称。 Impliesconnect=replicaSet. |
slaveOk=true|false | true:在connect=direct模式下,驱动会连接第一台机器,即使这台服务器不是主。在connect=replicaSet模式下,驱动会发送所有的写请求到主并且把读取操作分布在其他从服务器。false: 在 connect=direct模式下,驱动会自动找寻主服务器. 在connect=replicaSet 模式下,驱动仅仅连接主服务器,并且所有的读写命令都连接到主服务器。 |
safe=true|false | true: 在执行更新操作之后,驱动都会发送getLastError命令来确保更新成功。(还要参考 wtimeoutMS).false: 在每次更新之后,驱动不会发送getLastError来确保更新成功。 |
w=n | 驱动添加 { w : n } 到getLastError命令. 应用于safe=true。 |
wtimeoutMS=ms | 驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true. |
fsync=true|false | true: 驱动添加 { fsync : true } 到 getlasterror 命令.应用于 safe=true.false: 驱动不会添加到getLastError命令中。 |
journal=true|false | 如果设置为 true, 同步到 journal (在提交到数据库前写入到实体中). 应用于 safe=true |
connectTimeoutMS=ms | 可以打开连接的时间。 |
socketTimeoutMS=ms | 发送和接受sockets的时间。 |
可视化连接工具
Navicat For MongoDB: https://www.navicat.com.cn/products/navicat-for-mongodb
Studio 3T:https://studio3t.com/
NoSQL Manager for MongoDB: https://www.mongodbmanager.com/
Robo 3T:https://robomongo.org/
mongod
启动服务端
mogo shell
数据库操作
用户操作
创建用户:
修改用户:
集合操作
文档操作
插入
插入校验
检查文档基本结构是否正确,如果没有
_id
则自动增加一个id检查当文档是否小于16MB
mongodb校验有限,其他的校验通常在mongo客户端中进行
插入单条
批量插入
一次消息长度最多为48MB
如果插入总共大于48MB的数据,大部分驱动会将其拆分为多个批量插入请求
如果批量插入出现错误,那么错误文档之前的文档,都会被插入成功,后面的都会失败。如果想要忽略错误,需要增加
continueOnError
选项
查询
查询就是返回一个集合中符合条件的文档子集
find:查询所有文档
find:条件查询
find:$lt
、lte
、$gt
、$gte
find:$in
find:$or
、$and
find:$not
$not
是元语句,可以用在任何其他语句之上
find:过滤返回键
节省传输的数据量,也能减少客户端解码文档的内存消耗
_id
字段始终返回
find:返回单条
查询文档大小
删除
删除是永久性的,不可撤销,也不可能恢复
删除单条符合条件的文档
删除多条符合条件的文档
删除集合中的所有文档
不如使用
db.foo.drop()
更快更方便
更新
如果有两个客户端同时发送更新请求,先到达服务器的一方先执行,接着执行另一个
并发操作下是原子的,不会破坏文档
update
需要传入两个参数,第一个是查询文档,第二个是修改器文档更新修改器是原子性的,用于指定复杂的更新操作,比如修改、增加、删除键,操作数组、数字、或者内嵌文档
文档替换
使用新文档完全替换匹配的文档,replaceOne
:
更新单条
更新多条
$set
和unset
$set
用于修改字段的值甚至是类型,如果字段不存在,则创建该字段;而$unset
用于删除某个字段。
所得结果:
$inc
$inc
修改器用于增加键的值,如果键不存在就会创建。它可以用于整型、长整型、双精度浮点型的值,并且值必须为数字,不可是数字字符串,如果不是合法的值,将会造成操作失败。
数组修改器
$push
末尾增加单个元素:
结果:
$each
+ $push
一次在末尾添加多个值:
结果:
$slice
+ $push
$slice
的作用类似数组切片,指定一个数值,如果是正整数,则对数组的[0, n)
进行切片,如果值为负整数,则对数组从后往前进行切片,也就是(length-1-n, length-1]
索引
如何选择需要建立索引的字段?
如何强制使用索引?如何评估索引的效率?
创建索引和删除索引
什么是索引?为什么需要索引?
索引类似书的索引,记录某个数据的位置,不使用索引的查询称为全表扫描,全表扫描在搜寻某个字段时,会依次遍历表中的所有记录并查询该条记录的字段。所以当单张表数据很多时,这个操作将会非常耗时,所以需要使用索引解决这类问题。
索引可以根据给定的字段组织数据,让MongoDB能够非常快地找到目标文档。
最后更新于