第一章 mongodb简介
1.特点
| 特点 | 描述 |
|---|
| 易使用 | 面向文档的数据库,不是关系型数据库,不在有关系型数据库row(行)的概念,也不用提前定义表结构和字段的类型和大小,取而代之的是文档模型模型,通过在文档中嵌入文档和数组,可以使用一条记录来展现复杂的层次关系。文档不许要提前定义,key和value不是固定的大小和类型。所以删除和添加就非常容易,开发者可以快速迭代。开发更快。 |
| 易扩展 | 数据量增长过多的时候,存储也不端增长,分为纵向扩展和横向扩展,mongodb是横向扩展,将数据容易的在多态服务器减进行数据分割。可以自动处理跨集群的数据和负载。自动重新分配文档。将用户请求分配到正确的机器上。所以无需考虑扩展问题。只需要添加服务器。mongodb会自动将现有数据库向新服务器传送。 |
| 功能丰富 | 支持索引(提供唯一索引,复合索引,地理空间索引,全文索引。)支持聚合(通过简单的片段创建复杂的聚合,通过数据库自动优化)支持固定大小集合。支持时间有限的集合。过了时间就国企。用于保存日志。支持大文件和文件元数据的存储。不具备join,不具备多行事务。 |
| 性能卓越 | 文档进行动态填充,预分配数据文件,尽可能用内存做缓存,每次查询自动选择正确的索引。 |
2.版本特性
一般现在使用的都是3.0之后的版本。使用什么功能就选择什么版本。不是最新的版本就是最好的版本
| 版本 | 特性 |
|---|
| 2.x | 支持index,wirteConcern,readConcern |
| 3.0 | pluggable stroge engine,wiredtiger引擎(3.2之后默认的存储引擎),improved mmapv1 |
| 3.2 | raft协议,校验数据,支持部分索引,in-memory引擎(企业版支持),$lookup(关联查询,但比较弱) |
| 3.4 | 并行复制,sharding 迁移改进,collation sharding facet,graghLookup(与聚合相关) |
| 3.6 | 安全,并行性能提升,$lookup online 维护(在线oplog维护,在线添加字段) |
| 4.0 | Multi-document transaction,MongoDB4.0支持multi-document transaction,MongoDB4.2支持sharded clusters 多文档事务跨文档事务支持replica sets,但不支持Sharding集群,可以支持多个操作, 集合, 数据库和documents,多文档事务只支持WiredTiger 引擎 |
3.与MySQL对比
mongodb与mysql术语的对比。
| SQL | Mongodb |
|---|
| Database 数据库 | Database 数据库 |
| Table 表 | Collection 集合 |
| Row 行 | Document 文档 |
| Column 列 | Field字段 |
| Index 索引 | Index 类似,有很多变化 |
| Table joins 表连接 | $lookup 类似功能关联查询较弱 |
| Primary key 主键 | 可以指定,不指定使用_id |
| Aggregation聚合分组 | Aggregation pipeline 聚合管道,功能更强大,类似于hadoop逐级计算返回结果 |
| Transaction 事务 | Multi-document transaction 跨文档组合,需要使用复杂的集群支持。性能影响较大,功能比较弱。 |
第二章 mongodb基础
1.文档
文档是mongodb的核心概念,就是一个key和它的values组成的有序集,每个语言表达的方式不一样。比如映射map,散列hash,字典其实都是一个意思。类似于Mysql中的row行概念。
{"greeting":"Hello world!"}
上述就是一个文档,只有一个key名称是greeting,对应的值为hello world!。但大多数文档包含多个值。
{"greeting":"Hello world!","foo":3}
这个文档有两个key,greeting对应的值是hello wolrd,foo对应的值是3。
key可以使用任何的utf8的值。不能包含\0空字符,不能使用.和$具有特殊意义的字符。
mongodb 不区分类型,但是区分大小写,不能有重复的键值(key)。文档中的键/值是有序的(mongodb会重新排序)。
{"foo": 3} 3是数值类型
{"foo":"3"} 3是字符串类型
{"foo": 3}
{"Foo": 3} 是区分大小写的。两个文档也不相等。
{"greeting":"Hello world!","greeting":"Hello mnongo"} key值不能重复。
{"x":1,"y":2}与{"y":2,"x":1} 这两个文档是不同的。
2.集合
一组文档组成一个集合,类似于MySQL中的表概念。
对于集合来说,文档字段可以不同类型不同的值。但是应该将同类型的文档存放在同一个集合里面
不区分存放的话,要么确保每一次返回的是特性的类型,要不然执行查询的程序来处理不同类型文档,还要以区分。
一个集合查询特定的文档在速度上也不占优势。区分后查询效率更高。
同类型的存放在一个集合,数据更集中。磁盘io更少。
创建文档时,同一个类型文档,可以更有效的对集合进行索引。
集合的名称不能是,""空字符串,\0空字符,system.开头,不能包含$
子集合,使用.来区分不同命名空间的子集合。使用子集合来组织数据效率非常高效。
比如 db.blog 代表blog集合, db.blog.posts代表blog.posts集合。
3.数据库
多个集合组成一个数据库,一个实例可以有多个数据库,每个数据库有独立的权限,在磁盘上不同数据库存放在不同的文件夹中。
数据库命名
不能是空字符串"",/\,* < > $ ?
只能使用字母和数字
名称区分大小写,建议全部小写。
最多为64个字节长度
数据库会成为文件系统的文件,名称就是响应的文件名。
对于特定的数据库,admin(root数据库,一个用户添加到admin数据库,自动活的所有数据库权限,一些命令只能在admin数据库运行。比如列出数据库和关闭数据库),local(永远不可以复制。所有本地集合都可以保存在local数据库中)。config(用于分片设置,分片信息保存在config数据库中。)
4.数据类型
数据类型
null,{'x':null} 表示控制或者不存在的字段
布尔,{'x':true} true和false
数值,对于浮点数,默认使用64位浮点数值{'x':3},{'x':3.14}对于整数值{'x':NumberInt("3")}可以用numberInt类(表示4字节带符号整数){'x':NumberLong("3")}NumberLong(表示8字节带符号整数)
字符串,utf8字符。{'x':'avd124'}
日期,{'x': new Date()} 可以存储到毫秒数,记录的是当前的时间,不存储时区信息
正则,{'x':/foobar/i} 可以使用正则表达式作为限定条件。
数组,{'x':['a','b','c']} 可以表示数组列表
内嵌文档,{'x':{'foo':'bar'}} 可以嵌套文档,嵌套的文档作为父文档的值
对象id,{'x': ObjectId()} 是12字节的id,文档的唯一标识
二进制数据,不常用二进制是任意字节的字符串,不能再shell中使用,将非uft8的字符保存在数据库中。二进制是唯一方式代码,{'x':funcation(){}} 查询和文档中可以包含人和javascript代码
Date类
可以作为mongodb的日期类型。但是创建日期对象时,应使用 new Date()。 Date返回的时候日期的字符串表示,而非日期对象。结果跟mongodb无关,跟javascript的机制有关。对于使用混乱的日期对象和日期字符串。则它们之间无法匹配。执行删除更新的时候回导致很多问题。
shell 通过本地时区来显示日期对象。存储到毫秒数。。。对于时区可以用存储为另一个键的值。
db.blog.insertMany([
{'name':'use new date','date': new Date()},
{'name':'not use new date','date': Date()}
])
{ "_id" : ObjectId("5fc5acfce78f91ca2839cb1a"), "name" : "use new date", "date" : ISODate("2020-12-01T02:39:56.798Z") }
{ "_id" : ObjectId("5fc5acfce78f91ca2839cb1b"), "name" : "not use new date", "date" : "Tue Dec 01 2020 10:39:56 GMT+0800 (CST)" }
数组
是一组值,既可以是有序的对象 列表,栈,队列,也可以是无需对象 数据集来操作。数组可以包含不同类型的元素。常规的支持的所有值都可以作为数组的值,数组可以嵌套数组。mongodb可以理解数组结构。可以使用原子更新操作对数组内容进行修改。
内嵌文档
{
"name":"a",
"address:{
"city:"b",
state:"C"
}
}
mongodb可以理解内嵌文档的机构。可以深入构建索引,执行查询和更新。 好处是更直观更高效的展示。 坏处就是导致很多数据会重复。如果更新的话。会对一些相同的信息进行更新。只能按照多个条件一个一个的去更新。
_id和ObjectId
存储的文档必须要有一个_id键。值可以是人和类型,默认是ObjectId对象。每一个文档都有唯一的_id。
ObjectId 是_id默认类型。不同机器通过全局唯一的方法生成。mongodb为了分布式数据库为设计。这样的id可以在分片环境中生成唯一的标志符
使用12个字节的存储空间。由24个十六进制数字组成(每个字节存储2个16制)。连续创建的话。最初最后几个数字有变化。多了之后中间值有变化。
0 1 2 3 4 5 6 7 8 9 10 11
0 1 2 3 时间戳
4 5 6 机器
7 8 pid
9 10 11 计数器
0-8 组合提供秒级别的唯一性。时间戳的实际值不重要。不听增加不重复即可。
4-6 通常是主机名的hash值
7-8 保证同一台服务器的不同实例的ObjectId是唯一的,所以有进程的pid来产生
9-11 一秒钟最多运行每个进程有2563个不同的Objectid
对插入文档没有定义_id键。mongodb系统帮你自动创建。但通常在客户端驱动程序来完成自动定义_id键的工作无需mongodb来操作。扩展应用层要比扩展数据库层容易的多。
shell 交互式shell
不连接db,然后定义conn连接数据库。可以连接到不同的数据库和服务器上。
[root@~]# mongo --nodb
MongoDB shell version v4.2.7
conn = new Mongo("10.128.35.163:27017")
connection to 10.128.35.163:27017
db = conn.getDB("bill")
bill
可以直接执行js脚本。会依顺序执行传入的脚本。对于特定的数据库要指定(--quiet 不打印mongodb shell version那些一堆破信息)
mongo --quiet 10.128.35.163:30000/foo script.js scripts2.js
也可以使用load函数
load("script1.js")
辅助函数不可以在文件使用,可以使用对应的JavaScript函数
use db1 db.getSisterDB("db1")
show dbs db.getMongo().getDBs()
show collections db.getCollectionNames()
.mongorc.js
可以添加欢迎语。可以禁止dropDatabase或deleteIndexex 不能阻挡攻击。只是可以预防手误。
对于特定的集合,比如db.version,如果你访问这个集合。
不能直接db.version,因为它是db的一个方法。应该使用
db.getCollection("version")访问。
第三章 安装Mongodb(Linux)
1.使用YUM源来安装Mongodb社区版本
1.安装mongodb需要的依赖项
yum install libcurl openssl -y
2.使用阿里云镜像
cat /etc/yum.repo.d/mongo.repo
[mongodb-org]
name=MongoDB Repository
baseurl=http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/4.0/x86_64/
gpgcheck=0
enabled=1
3.通过yum安装mongodb
yum install mongodb-org -y
4.启动mongodb
systemctl start mongod
systemctl enable mongod
5.连接mongodb
mongo –host 127.0.0.1 27017
6.卸载
systemctl stop mongod ——停止mongo服务
yum erase $(rpm –qa|grep mongo-org) ——卸载mongodb的yum包
rm –rf /var/log/mongodb ——删除mongodb数据
rm –rf /var/lib/mongo ——删除mongodb数据
第四章 常用命令
1.增删改查
| Command | 作用 |
|---|
| db.collection.insert() | 在集合中创建或插入新文档 |
| db.collection.insertOne() | 在集合中插入新文档 |
| db.collection.insertMany() | 在集合中插入几个新文档 |
| db.collection.update() | 修改集合中的文档 |
| db.collection.updateOne() | 修改集合中的单个文档 |
| db.collection.updateMany() | 修改集合中的多个文档 |
| db.collection.save() | 如果不在就insert插入,如果存在就update更新 |
| db.collection.deleteOne() | 删除集合中的单个文档 |
| db.collection.deleteMany() | 删除集合中的多个文档 |
| db.collection.find() | 对集合或视图执行查询并返回游标对象 |
| db.collection.findAndModify() | 以原子方式修改并返回单个文档 |
| db.collection.findOne() | 执行查询并返回单个文档 |
| db.collection.findOneAndDelete() | 查找单个文档并将其删除 |
| db.collection.findOneAndReplace() | 查找单个文档并替换它 |
| db.collection.findOneAndUpdate() | 查找单个文档并进行更新 |
| db.collection.distinct() | 去重 |
| db.collection.mapReduce() | 执行map-reduce样式数据聚合 |
| db.collection.aggregate() | 提供对聚合管道的访(group的替代) |
| db.collection.bulkWrite() | 提供批量写入操作功能 |
2.索引相关
| Command | 作用 |
|---|
| db.collection.createIndex() | 在集合上构建索引 |
| db.collection.createIndexes() | 在集合上构建一个或多个索引 |
| db.collection.dropIndex() | 删除集合上的指定索引 |
| db.collection.dropIndexes() | 删除集合上的所有索引 |
| db.collection.getIndexes() | 返回描述集合上现有索引的文档数组 |
| db.collection.reIndex() | 重建集合上的所有现有索引 |
3.集合状态
| Command | 作用 |
|---|
| db.collection.count() | 返回文档数量 |
| db.collection.countDocuments() | group使用sum 表达式包装聚合阶段以返回集合或视图中文档数的计数 |
| db.collection.dataSize() | 返回集合的大小 |
| db.collection.estimatedDocumentCount() | 返回文件的大概数量 |
| db.collection.drop() | 从数据库中删除指定的集合 |
| db.collection.explain() | 返回操作的执行计 |
| db.collection.isCapped() | 集合是否为固定大小的集合,是的话不能分片,新数据覆盖老数据 |
| db.collection.renameCollection(“newname”) | 更改集合的名称 |
| db.collection.stats() | 报告集合的状态 |
| db.collection.storageSize() | 报告集合使用的总大小(以字节为单位) |
| db.collection.totalIndexSize() | 报告集合上索引使用的总大小 |
| db.collection.totalSize() | 报告集合的总大小,包含索引和文档数据 |
| db.collection.validate() | 对集合执行诊断操作 |
| db.collection.latencyStats() | 返回集合的延迟统计信息 |
| db.collection.replaceOne() | 替换集合中的单个文档 |
| db.collection.watch() | 在集合上建立变更流 |
| db.collection.validate() | 对集合执行诊断操作 |
4.数据库相关
| Command | 作用 |
|---|
| show dbs | 显示所有数据库 |
| use dbs | 进入数据库,无定义可进入(但show dbs不显示,创建了集合数据库就显示出来了 |
| db.help() | 显示常用db对象方法的描述 |
| db.adminCommand() | 对admin数据库运行命令 |
| db.aggregate() | 运行不需要基础集合的管理/诊断管道 |
| db.cloneCollection() | MongoDB实例之间复制数据 | 包装cloneCollection,不支持分片 |
| db.createCollection() | 创建新集合或视图 | 常用于创建上限集合 |
| db.createView() | 创建一个视图 |
| db.currentOp() | 报告当前正在进行的操作 |
| db.dropDatabase() | 删除当前数据库 |
| db.fsyncLock() | 将mongod的写入操作刷新到磁盘并锁定mongod实例 |
| db.fsyncUnlock() | 允许写入在锁定的数据库上继db.fsyncLock() | |
| db.getCollection() | 返回集合或视图对象 | 用于访问名称在mongoshell中无效的集合 |
| db.getCollectionInfos() | 返回当前数据库中所有集合和视图的集合信息 |
| db.getCollectionNames() | 列出当前数据库中的所有集合和视图 |
| db.getLastError() | 检查并返回上一次操作的状态 | 包裹getLastError |
| db.getLastErrorObj() | 返回上一个操作的状态文档 | 包裹getLastError |
| db.getLogComponents() | 返回日志消息详细级别 |
| db.getMongo() | 返回Mongo() | 当前连接的连接对象 |
| db.getName() | 返回当前数据库的名称 |
| db.getProfilingLevel() | 返回数据库操作的当前分析级别 |
| db.getProfilingStatus() | 返回反映当前性能分析级别和性能分析阈值的文档 |
| db.getReplicationInfo() | 返回包含复制统计信息的文档 |
| db.getSiblingDB() | 提供对指定数据库的访问 |
| db.hostInfo() | 返回一个文档,其中包含有关MongoDB运行的系统的信息 |
| db.isMaster() | 返回报告副本集状态的文档 |
| db.killOp() | 终止指定的操作 |
| db.listCommands() | 显示常用数据库命令的列表 |
| db.logout() | 结束经过身份验证的会话 |
| db.printCollectionStats() | 打印每个集合的统计信息 |
| db.collection.stats() | 打印单个集合的统计 |
| db.printReplicationInfo() | 从主数据库的角度打印副本集状态的报告 |
| db.printShardingStatus() | 打印分片配置和块范围的报告 |
| db.printSlaveReplicationInfo() | 从辅助节点的角度打印副本集状态的报告 |
| db.repairDatabase() | 在当前数据库上运行修复例程 |
| db.runCommand() | 运行数据库命令 |
| db.serverBuildInfo() | 返回显示mongod实例的编译参数的文档 | 包裹buildinfo |
| db.serverStatus() | 返回一个文档,该文档提供数据库进程状态的概述 |
| db.setLogLevel() | 设置单个日志消息详细级别 |
| db.setProfilingLevel() | 修改当前的数据库分析级别 |
| db.shutdownServer() | 干净的关闭mongod或mongos进程 |
| db.stats() | 返回报告当前数据库状态的文档 |
| db.version() | 返回mongod实例的版本 |
5.用户相关
| Command | 作用 |
|---|
| db.auth() | 将用户验证到数据库 |
| db.changeUserPassword() | 更改现有用户的密码 |
| db.createUser() | 创建一个新用户 |
| db.dropUser() | 删除单个用户 |
| db.dropAllUsers() | 删除与数据库关联的所有用户 |
| db.getUser() | 返回有关指定用户的信息 |
| db.getUsers() | 返回有关与数据库关联的所有用户的信息 |
| db.grantRolesToUser() | 向用户授予角色及其权限 |
| db.revokeRolesFromUser() | 从用户中删除角色 |
| db.updateUser() | 更新用户数据 |
6.监控相关
| Command | 作用 |
|---|
| Monitoring | 检测相关 |
| db.enableFreeMonitoring() | 在运行时启用免费监控 |
| db.disableFreeMonitoring() | 在运行时禁用自由监视 |
| db.getFreeMonitoringStatus() | 返回自由监视状态 |
7.角色相关
| Command | 作用 |
|---|
| db.createRole() | 创建角色并指定其权限 |
| db.dropRole() | 删除用户定义的角色 |
| db.dropAllRoles() | 删除与数据库关联的所有用户定义角色 |
| db.getRole() | 返回指定角色的信息 |
| db.getRoles() | 返回数据库中所有用户定义角色的信息 |
| db.grantPrivilegesToRole() | 为用户定义的角色分配权限 |
| db.revokePrivilegesFromRole() | 从用户定义的角色中删除指定的权限 |
| db.grantRolesToRole() | 指定用户定义的角色从中继承权限的角色 |
| db.revokeRolesFromRole() | 从角色中删除继承的角色 |
| db.updateRole() | 更新用户定义的角色 |
8.分片相关
| Command | 作用 |
|---|
| db.collection.getShardDistribution() | 对于分片集群的集合,报告分布的数据 |
| db.collection.getShardVersion() | 分片群集的内部诊断方法 |
9.副本集相关
| Command | 作用 |
|---|
| rs.add() | 将成员添加到副本集 |
| rs.addArb() | 将仲裁器添加到副本集 |
| rs.conf() | 返回副本集配置文档 |
| rs.freeze() | 阻止现任成员在一段时间内寻求选举 |
| rs.initiate() | 初始化新的副本集 |
| rs.printReplicationInfo() | 检查oplog日志大小,时间和范围 |
| rs.printSlaveReplicationInfo() | 检查成员复制的延迟 |
| rs.reconfig() | 通过应用新的副本集配置对象重新配置副本集 |
| rs.remove() | 从副本集中删除成员 |
| rs.status() | 返回包含有关副本集状态的信息的文档 |
| rs.stepDown() | 导致当前的初选成为强制选举的次要 |
| rs.syncFrom() | 设置此副本集成员将同步的成员,覆盖默认同步目标选择逻辑 |
| db.getMongo().setReadPref('primaryPreferred') | 设置读取操作 |
| primary默认参数,只从主节点上进行读取操作 |
| primaryPreferred大部分从主节点读取,主不可用的时候在从上读取 |
| secondary,只从secondary节点上进行读取操作,问题是主数据没写到从上 | 从可能查不到 |
| secondaryPreferred优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据 |
| Nearest 不管是主节点、secondary节点,从网络延迟最低的节点上读取数 |
| db.serverStatus() | 展示服务器的所有状态 |
| db.serverStatus().storageEngine | 查询当前默认的存储引 |
| supportsCommittedRead | 支持提交读,当一个修改提交后,其他的连接才能读 |