目录
MongoDB简介
前言:MongoDB是一个开源、高性能、无模式的文档型数据库,当初设计就是为了简化开发和方便扩展,是nosql数据库中产品的一种;是最像关系型数据库的非关系型数据库
注意:MongoDB中的记录是一个文档,他是一个由字段和值对组成的数据结构。MongoDB文档类似于json对象,即一个文档就认为是一个对象。字段的数据类型是字符型,他的值除了可以使用基本的类型外还可以包括其他文档,普通数组和文档数据
使用mongoDB原因
- 由于mongoDB独特的数据处理方式,可以将热点数据加载到内存,故而对查询来讲会非常快(当然也会非常消耗内存)
- 由于采用了BSON(二进制JSON)的方式存储数据,故而对JSON格式数据具有非常好的支持性以及友好的表结构修改性
- 文档的存储方式,数据友好可见
- 数据库的分片集群负载具有非常好的扩展性以及非常不错的自动故障转移
MongoDB与mysql的区别
BSON所支持的数据类型
mongoDB安装后的目录
mongoDB的启动方式
命令行加参数的形式
前言:进入mongoDB的bin目录,按cmd在此处打开命令行
- 启动客户端:点击mongo.exe或者直接进入命令行输出mongo [--host=127.0.0.1 --post=27017]
- 启动服务端:进入命令行输入mongod --dbpath=..\..\data
注意:启动服务端与客户端均需要在mongoDB的bin目录进行,启动服务端命令后有--dbpath的参数,该参数的意义为将后面的路径作为启动服务端的根据地;只要启动了服务端就会出现黑窗口,该黑窗口代表服务端启动中,从启动日志中可以看出mongoDB的默认端口为27017.
命令行加配置文件的形式
前言:在与bin目录的同级目录下创建conf文件夹,并在里面存放配置文件mongod.conf(里面输入以下内容)
systemLog:
#mongoDB发送的所有日志为文件类型
destination: file
#配置日志的地址
path: "../../log/mongod.log"
#当mongos或mongod实例重启后,mongos或mongod是否会将新条目追加到现有日志的末尾
logAppend: true
storage:
#mongod实例储存的文件路径
dbPath: "../../data"
journal:
#启用或禁用持久性日志以确保数据文件保持有效和可恢复
enabled: true
net:
#服务器实例绑定的ip,默认为localhost
bindIp: localhost
#绑定的端口,默认为27017
port: 27017
注意:该yaml格式的文件格式严格,每级之间用一个空格表示
敲击命令:mongod -f ..\conf\mongod.conf或者mongod --config ..\conf\mongod.conf
数据库相关操作
数据库操作命令
选择和创建数据库名称:use 数据库名称
查看所有数据库名称:show dbs或show databases
展示当前所在的数据库:db或db.getName()
显示当前数据库状态:db.stats()
查看当前数据库版本:db.version()
删除当前的已经持久化了的数据库:db.dropDatabase()
注意:
- 当且仅当数据库有内容的时候,其才可以被show dbs在磁盘中查询到,不然该数据库仅仅存在内存中
- mongoDB中默认的数据库为test,若你没有选择数据库,那么集合将存放在test数据库中
MongoDB数据库命名规则
- 不能是空字符串
- 不得含有‘ ’(空格)、点、$、/、\和\0(空字符)
- 应全部小写
- 最多64个字节
- 满足以上条件的任意UTF-8字符串
MongoDB保留数据库
- admin:从权限的角度看,这是root数据库。若将用户添加到在这个数据库,这个用户自动继承所有数据库权限。一些特定的服务端命令也只能从这个数据库中运行,比如列出所有数据库或者关闭服务器
- local:在该数据库里面的数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息
集合的操作
前言:集合类似于关系型数据库中的表
创建集合:db.createCollection("集合名称",{size:5242880,capped:true,max:5000})
注意:capped为true表示创建固定长度的集合,size表示了集合的最大存储空间(5mb),max表示集合最大有多少文档的个数
查看当前数据库中的集合:show collections或show tables
得到当前数据库集合的所有状态信息:db.printCollectionStats()
集合的删除:db.集合名称.drop()
文档基本的CRUD
前言:文档类似于关系型数据中的行,其数据结构和JSON基本一样,所有存储在集合中的数据都为BSON格式
文档的插入
使用insert或save方法向集合中插入数据
向集合中插入数据:db.集合名称.insert([{属性1:值1,属性2:值2},{属性1:值3,属性4:值4}],{order:true})
注意:
- 该向集合中插入数据,若插入的数据仅有1条则外面的[]可以省略;
- 插入的多个文档其中的key可以一样也可以不一样(不一样可能会在其他行中留空)
- insert也可以用save代替
- 多个文档的插入尽量用insertMany代替
- order属性为可选参数,若不写默认为true,表示按顺序插入数组中的文档,若一个文档出错,则mongo将返回而不处理数组中的其余文档;若为假则执行无序插入,若一个文档出错则继续处理数组中的主文档
- 插入过程中若没有_id属性则mongoDB会自动生成_id属性并将其作为主键
- 若某条数据插入失败,将会终止插入;但已经插入成功的数据不会回滚掉,所以我们应借助try-catch语法,进而对异常进行处理(mongoDB没有事务特性)
文档的更新
基本数值的修改
语法:db.集合名称.update({查询条件},{$set:{修改条件}},{基本设置})
//在集合you内将_id为1的name属性值改为lucy,age值改为18
db.you.update({_id:1},{$set:{name:"lucy",age:18}})
数值增长的修改
语法:db.集合名称.update({查询条件},{$inc:{属性:属性值}},{基本设置})
//在集合有内将age为3并且sex为男的文档name属性值改为nana,age值改为age+1
db.you.update({age:3,sex:"男"},{$set:{name:"nana"},$inc:{age:1}})
基本设置
multi:true为设置批量修改,若没有设置批量修改,那么当多个文档需要修改时,只会修改第一个文档
//在you集合内将name为liu的文档name值全改为nana,sex值全改为女
db.you.update({name:"liu"},{$set:{name:"nana",sex:"女"}},{multi:true})
文档的删除操作
删除命令
删除集合中的所有文档:db.集合名称.remove({})
删除集合中特定条件的文档:db.集合名称.remove({条件})
//删除you集合中name为nana并且age为10的文档
db.you.remove({name:"nana",age:10})
文档的查询
查看集合中所有记录:db.集合名.find({})
根据条件来查询
查询符合条件的所有记录:db.集合名.find({查询条件},{是否显示属性})
查询符合条件的一条记录:db.集合名.findOne({查询条件},{是否显示属性})
注意:后面的是否显示属性参数想显示那个列就将那个列设置为1,不想显示那列就将那列设为0
//查询my集合内name为lili并且sex为女的所有文档,并且只显示name和age字段
db.my.find({name:"lili",sex:"女"},{_id:0,name:1,age:1})
正则条件查询
语法:db.集合名称.find({name:/正则表达式/})
注意:该正则表达式的写法为js正则表达式的写法
比较查询
语法:db.集合名称.find({属性名:{$比较符:比较的数值}})
//在article集合中查询age大于12的文档
db.article.find({age:{$gt:12}})
//在article集合中查询age小于12的文档
db.article.find({age:{$lt:12}})
//在article集合中查询age大于等于12的文档
db.article.find({age:{$gte:12}})
//在article集合中查询age小于等于12的文档
db.article.find({age:{$lte:12}})
//在article集合中查询age不等于12的文档
db.article.find({age:{$ne:12}})
包含查询
包含查询主要用$in和$nin操作符
语法:db.集合名称.find({属性:{$包含操作符:[数值1,数值2]}})
理解:查询在集合中属性值满足或不满足后面集合元素的所有文档
//在article集合中查找age满足10和18的所有文档
db.article.find({age:{$in:[10,18]}})
//在article集合中查找age不满足10和18的所有文档
db.article.find({age:{$nin:[10,18]}})
条件连接查询
我们若需要查询同时满足两个以上的条件则需要使用$and操作符将条件进行关联
语法:db.集合名称.find({$and:[{条件1},{条件2}]},{是否显示属性})
//在article集合中查询9<age<15的文档,不显示_id属性
db.article.find({$and:[{age:{$gt:9}},{age:{$lt:15}}]},{_id:0})
若我们查询的条件为或者关系,那么就需要用到$or操作符
语法:db.集合名称.find({$or:[{条件1},{条件2}]},{是否显示属性})
//在article集合内查询name为lili或age为12的所有文档,不显示_id属性
db.article.find({$or:[{name:"lili"},{age:12}]},{_id:0})
统计记录
统计所有的记录数:db.集合名称.count()
统计符合条件的记录数:db.集合名称.count({条件})
文档的分页查询
可以使用limit(数字)方法来读取指定数量的数据,用skip(数字)方法来跳过指定数量的数据
语法:db.集合名称.find().skip(m).limit(n)
理解:查询集合m(默认为20)个文档之后的n(默认为0)个文档
文档的排序查询
可以使用sort()方法对数据进行排序,sort()可以通过参数指定排序的字段,并使用1/-1代替排序方式(1:升序;-1:降序)
语法:db.集合名称.find().sort({属性1:排序方式,属性2:排序方式})
//在article集合内查到的所有文档中先以age进行降序排序,若age相同则以_id为降序排序
db.article.find().sort({age:-1,_id:-1})
注意:limit()、skip()、sort()等函数都需要使用在find()函数之后,若sort()、limit()、skip()三个放在一起执行的时候,执行顺序为先sort(),再skip(),最后limit();这和命令的编写顺序无关
索引
概述
- 索引支持在mongoDB中高效的执行查询,若没有索引,mongoDB必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。这种扫描全集合的效率非常低
- 若查询存在适当索引,mongoDB可以使用该索引限制必须检查的文档数
- 索引是特殊的数据结构,它以易于遍历的形式存储集合数据的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB还可以使用索引中的排序返回排序结果
- MongoDB索引使用的是B-Tree的数据结构
索引的类型
单字段索引
含义:MongoDB支持在文档上的单个字段上创建用户自定义的升序/降序索引,称为单字段索引
注意:对于单个字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任何方向上遍历索引
复合索引
含义:MongoDB还支持多个字段的用户定义索引
注意:复合索引中列出的字段顺序具有重要意义,例如:若复合索引由{userid:1,score:-1}组成,则索引首先会按userid正序排序,然后在每个userid的值内,再按score倒序排序
其他索引
- 地理空间索引(geospatial Index):为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引:返回结果时使用平面几何的二维索引和返回结果时使用球面几何的二维球面索引
- 文本索引(Text Indexes):该索引支持在集合中搜索字符串内容。
- 哈希索引(Hashed Indexes):为了支持基于散列的分片,MongoDB提供了散列索引的类型,它对字段值的散列进行了索引。这些索引在其范围内的值分布更加随机,但只支持相等匹配,不支持基于范围的查询
索引的管理操作
索引的查看
返回集合中的所有索引:db.集合名.getIndexes()
索引的创建
创建索引:db.集合名.createIndex({列1:排序方式,列2:排序方式},options)
options
- unique:建立的索引是否唯一,若唯一则为true,否则为false(默认为false)
- name:建立索引的名称(为string类型)若未指定,mongoDB会通过连接索引的字段名和排序顺序生成一个索引名称
//为article集合的age字段建立一个升序单字段索引,并取名为age_index
db.article.createIndex({age:1},{name:"age_index"})
移除索引
根据索引名移除索引:db.集合名.dropIndex("索引名称")
根据规范移除索引:db.集合名.dropIndex({列1:排序方式,列2:排序方式})
移除所有的索引:db.集合名.dropIndexes()
注意:主键索引(_id)永远不会被移除
索引的使用
执行计划
作用:分析查询性能通常使用执行计划来查看查询的情况,如查询耗费的时间,是否基于索引查询等
语法:db.集合名称.find({查询条件,是否显示属性}).explain()
注意:主要看winningPlan的stage属性值(COLLSCAN:全集合扫描,FETCH:索引抓取)
涵盖查询
前言:当查询条件和查询的投影仅仅包含索引字段时,MongoDB直接从索引返回结果,而不扫描任何文档或将文档带入内存
理解:类似于mysql的索引覆盖