学习目标

  • 了解Mongodb是什么?

一、NoSql数据库与MongoDB简介

二、MongoDB基本操作

下面将学习CRUD基本操作

MongoDB特性

  • 文档主键具有唯一性 (与SQL主键一致)
  • 支持所有数据类型(数组以外)
  • 复合主键(后续讲解)

在日常使用Mogodb中,如果我们没有指定文档主键,Mogodb驱动会自动帮我们生成文档主键也就是对象主键objectId

创建数据库

MongoDB 创建数据库的语法格式如下:

  1. > use database_name

切换到指定数据库,如果数据库不存在,则创建并进入数据库

示列

> use school
switched to db student
> db #查看当前操作的文档(数据库)
school
>

如果你想查看所有数据库,可以使用 show dbs 命令:

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

可以看到,我们刚创建的数据库 student并不在数据库的列表中, 这是因为数据库目前存在内存中,要显示它,我们需要向 runoob 数据库插入一些数据。

> db.student.insert({name:"jac"})
WriteResult({ "nInserted" : 1 })
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
school  0.000GB

上述代码中student表中有了数据,那么mongodb必须把student表数据文件创建并保存到硬盘中。

创建文档

创建集合

db.createcollection("collectionname")

删除集合

MongoDB 删除集合(数据库表)的语法格式如下:

db.collection.drop()

插入文档

MongoDB用BSON(二进制JSON)来保存数据。一条记录就是一条文档,某些文档聚集到一起,就形成了集合。

db.collectionname.insert(document)插入单条或多条文档
db.collectionname.insertMany([document,document])插入单条或多条文档
或

db.collectionname.save(document)

读取文档

MongoDB适合保存海量低价值数据

NoSQL数据库简介

NoSQL泛指非关系数据库,随着web2.0和web3.0的技术的兴起,传统关系型数据库无法应对如此巨大的数据存储和处理,所以非关系型数据库得以发展,NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。

MongoDB和redis一样属于nosql的范畴,但是两者不同区别在于redis是内存缓存数据,mongodb是硬盘存储数据,前者存储数据少,后者存储数据量大。

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

MongoDB 下载

MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制包下载地址:https://www.mongodb.com/download-center/community

image.png
image.png

image.png

image.png
image.png
Mongodb默认是不需要用户密码就可以连接的,如果使用命令报错”not authorized on admin to execute command “,则表示当前登陆用户不具备相应权限;

MongoDB - 图6

WriteCommandError({
        "ok" : 0,
        "errmsg" : "not authorized on school to execute command { insert: \"school\", ordered: true, lsid: { id: UUID(\"56655141-93a9-446b-9d2a-04ecc6e74205\") }, $db: \"school\" }",
        "code" : 13,
        "codeName" : "Unauthorized"

解决办法:通过创建一个用户,赋予用户root权限

db.createUser(
    {
        user:"root",
        pwd:"123456",
        roles:[{role:"root",db:"admin"}]
    }
);

添加用户权限成功之后,使用root用户登陆,再次使用命令即可成功!!!

MongoDB - 图7
附:添加用户时各个角色对应权限

1.数据库用户角色:read、readWrite; 2.数据库管理角色:dbAdmin、dbOwner、userAdmin; 3.集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager; 4.备份恢复角色:backup、restore 5.所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase 6.超级用户角色:root

MongoDB 语法

删除数据库

MongoDB 删除数据库的语法格式如下:

db.dropDatabase()

删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名。
示列
首先,查看所有数据库:

> show dbs
config  0.000GB
local   0.000GB
admin   0.000GB
school  0.000GB

如果想删除数据库 , 那么db. dropDatabase() 命令如下:

> use admin
switched to db admin
> db.dropDatabase()
{ "dropped" : "admin", "ok" : 1 }
>

示列
首先,查看数据库中的所有集合(类似数据库中的表):

> use school
switched to db school
> show collections #或者 show tables
teacher
student

如果想删除集合 , 那么 db.collection.drop()命令如下:

> db.teacher.drop()
true
> show tables
school

MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。

注意:_ 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。_MongoDB 图形化客户端

查看集合记录数量

> use school
switched to db school
> db.student.count() 
0

查看集合空间容量

> use school
switched to db school
> db.student.dataSize() 
0

重命名集合

> use school
switched to db school
> db.student.renameCollection("teacher")

修改文档

db.collection.update({condition},{$set:{data}}) 
//update()只能修改一条数据,即使存在相同的条件,也只会修改第一条

db.collection.updatemany({condition},{$set:{data}})
//updatemany()只能修改一条数据,即使存在相同的条件,也只会修改第一条

db.collection.updatemany({condition},{$unset:{data}})
//$unset可以删除记录中的字段

db.collection.updatemany({condition},{$inc:{data}})
//$inc可以做加法运算

示列

> db.teacher.update({name:"小白"},{$set:{age:35}})
Updated 1 existing record(s) in 9ms
//找到小白,修改他的年龄为35

> db.teacher.updateMany({sex:"男",age:{$gte:18}},{$set:{age:30}})
//把大于等于26的男老师,年龄改成40


> db.teacher.updateMany({},{$unset:{age:35}})
//{}无条件查询每条记录,删除每条记录的某个字段属性


> db.teacher.updateMany({},{$inc:{age:18}})

//{}无条件查询每条记录,把每条记录的age属性值加上18


db.teacher.update({},{$push:{role:"辅导员"}})

db.teacher.update({},{$pull:{role:"辅导员"}})

删除文档

删除文档使用remove()函数,该函数接收一个参数{query},{}为空表示无条件删除所有记录,如果要指定删除条件就得写到{}里

db.collection.remove({query})  //query 表示条件

演示

db.teacher.remove({})
//删除teacher集合中的所有记录

db.teacher.remove({name:"小明",age:35})
//删除所有符合name=小明,age=18的记录

mongdb是nosql数据库,他仅仅对读写速度进行了优化,并没有功能集群和运算函数。

  • Robo 3T是目前可视化最好的MongoDB图形化客户端,而且是免费的,你可以从robomongo公司官网下载安装,Robo 3T 下载地址:https://robomongo.org/download

image.png
Failed to load list of database Failed to execute “listdatabases” command.
https://blog.csdn.net/fxf971989229/article/details/85074185

Studio 3T是robomongo公司官推出功能更强大的MongoDB图形化客户端,他支持使用SQL语句转换成JavaScript代码去操作mongodb,该软件为商业软件有30天试用时间。
image.png
image.png

MongoDB 用户管理

  • 内置角色一

以下四个角色的权限仅限于某个逻辑库,不能操作其他逻辑库

序号 角色 权限
1 Read 允许用户读取指定逻辑库
2 readWrite 允许用户读写指定逻辑库
3 dbAdmin 可以管理指定逻辑库
4 userAdmin 可以管理指定逻辑库的用户
  • 内置角色二

以下四个角色的只能创建在admin逻辑库,可以管理其他逻辑库

序号 角色 权限
1 readAnyDatebase 用户只能创建在admin逻辑库,允许用户读取任何逻辑库
2 readWriteAnyDatebase 用户只能创建在admin逻辑库,允许用户读写任何逻辑库
3 dbAdminAnyDatebase 用户只能创建在admin逻辑库,允许管理任何逻辑库
4 userAdminAnyDatebase 用户只能创建在admin逻辑库,允许管理任何逻辑库的用户
  • 内置角色三

以下二个角色的也只能创建在admin逻辑库,root是最高权限

序号 角色 权限
1 clusterAdmin 用户只能创建在admin逻辑库,允许管理MongoDB集群
2 root 用户只能创建在admin逻辑库,超级管理员拥有最高权限

首先切换到admin逻辑库,然后创建root角色用户

> use admim
switched to db admin
> db.createUser(
    {
        user:"yu311",
        pwd:"123456",
        roles:[{role:"root",db:"admin"}] #将yu311用户赋予root角色权限,将yu311用户归属于admin逻辑库
    }
)

image.png
image.png
yu123是root角色,而root角色属于admin逻辑库,所以要先切换到admin逻辑库,才能开启auth验证

image.png
结构比较松散,应为每个bson中的属性数据是可以不同的,所以 在保存记录的时候省却了字段约束的检查 ,读写速度更快

MongoDB索引

因为mongodb是nosql数据库,存放的数据远超过mysql数据库,如果没有索引,一个查询的请求,会让mongodb做全表扫描,这种检索效率是非常低的,一次查询会花费几十秒或几分钟的时间, 所以索引机制对于在海量数据中快速定位查找数据就显得非常重要了。

与mysql索引机制相同,mongodb的索引提升数据的检索速度,原理是先对数据进行排序,
索引的作用是为了提升查询效率,在查询操作中,如果没有索引,MongoDB 会扫描集合中的每个文档,以选择与查询语句匹配的文档。如果查询条件带有索引,MongoDB 将扫描索引, 通过索引确定要查询的部分文档,而非直接对全部文档进行扫描。

插入索引

db.collection.createlndexes({字段:1},options) //1正序 -1表示降序 options是json格式的参数

db.collection.createlndex ({ "字段" : 1 }, { background: true,name:"字段名"})
//使用createlndex函数为字段添加索引,background参数表示在mongodb空闲时创建索引,name参数表示为索引名

删除索引

db.teacher.dropIndex("name_1")//删除指定索引,接收一个索引名字
或
db.teacher.dropIndexes() //删除集合上的所有索引

列出索引

返回集合上所有索引

db.collection.getlndexes()

image.png
唯一性索引

db.collection.createlndex ({ "sid" : 1 }, { background: true,unique: true })
> db.teacher.createIndex({ "sid" : 1 }, { background: true,unique: true })
Updated 1 existing record(s) in 9ms

//找到小白,修改他的年龄为35
> db.teacher.save({name:"杰克",sid:101})
E11000 duplicate key error collection: school.teacher index: sid_1 dup key: { sid: 101.0 } //重复创建sid索引

创建索引原则

  • 数据量很大的集合需要创建索引,相反则不需要创建索引
  • 读多写少:集合的数据读取多过写入,则需要创建索引,因为索引提升的是查询速度,正好适合读多写少场景。读少写多:不适合添加索引,也不会提升写入速度,反而会拖慢写入速度,因为写入和修改都会导致数据的排序。
  • 经常被当做查询条件的字段设置索引,不经常被当做查询条件的字段不用设置索引