MongoDB学习笔记1:基础
1 MongoDB介绍
1.1 MongoDB是什么
MongoDB是面向文档的NoSQL数据库,用于大量数据存储。MongoDB是一个在2000年代中期问世的数据库。属于NoSQL数据库的类别。
1.2 MongoDB的特点
- MongoDB 是一个面向文档存储的数据库,它不是以关系类型的格式存储数据,而是将数据存储在文档中。这使得 MongoDB 非常灵活,可以适应实际的业务环境和需求。
- MongoDB支持索引,可以创建索引来提高MongoDB的搜索性能
- 负载均衡,MongoDB使用分片的概念,通过在多个MongoDB实例之间拆分数据来水平扩展
- MongoDB还支持动态查询、全文搜索 、聚合框架、MapReduce、GridFS、地理位置索引、内存引擎 、地理分布等一系列的强大功能。
1.3 MongoDB相关术语
- 数据库:存储表的容器,在MongoDB中是存储集合的容器,可以创建多个数据库
- 集合(collection):相当于关系型数据库中的表,集合存在于单个的数据库中
- 文档(Document):相当于关系型数据库中数据表的行,在mongo中叫做文档,一个文档包含字段名称和值
2 MongoDB的部署
-
MongoDB官网:https://www.mongodb.com/
-
MongoDB软件下载:https://www.mongodb.com/try/download/community
软件版本
这里我安装 mongodb-linux-x86_64-rhel70-4.2.17.tgz
版本
本机环境说明
[root@web01 ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
[root@web01 ~]# uname -a
Linux web01 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[root@web01 ~]# hostname -I
192.168.5.50
[root@web01 ~]# getenforce
Disabled
[root@web01 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
安装步骤
# 下载软件包
$ cd /usr/local/src && wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.17.tgz
# 解压
$ tar -xvf mongodb-linux-x86_64-rhel70-4.2.17.tgz
# 移动指定目录
$ mv mongodb-linux-x86_64-rhel70-4.2.17 /usr/local/mongodb
# 创建用户和组,并设置用户密码
$ useradd mongod
$ echo '123qwe321' | passwd --stdin mongod
# 创建mongodb的配置文件目录,日志目录和数据目录
$ mkdir -p /mongodb/{conf,log,data}
# 设置目录权限
$ chown -R mongod:mongod /mongodb/
# 设置用户环境变量
$ su - mongod
# 编辑.bashrc配置文件,添加mongo的环境变量
$ echo 'export PATH=/usr/local/mongodb/bin:$PATH' >> .bashrc
$ source .bashrc
使用配置文件启动mongodb
Mongodb有两种配置文件,一种跟mysql的配置文件类似,INI格式的,一种是yaml格式的,官方从3.x开始推荐使用yaml格式。
# 创建配置文件
$ cat > /mongodb/conf/mongo.conf <<EOF
systemLog:
destination: file
path: "/mongodb/log/mongodb.log"
logAppend: true
storage:
journal:
enabled: true
dbPath: "/mongodb/data/"
processManagement:
fork: true
net:
port: 27017
bindIp: 192.168.5.50, 127.0.0.1
EOF
启动和关闭
# 以 mongod 用户启动和关闭
$ su - mongod
# 启动 mongoddb
$ mongod -f /mongodb/conf/mongo.conf
# 关闭 mongodb
$ mongod -f /mongodb/conf/mongo.conf --shutdown
配置文件说明
systemLog:
destination: file
path: "/mongodb/log/mongodb.log" -- 日志位置
logAppend: true -- 日志以追加模式记录
storage:
journal:
enabled: true
dbPath: "/mongodb/data" -- 数据保存的位置
processManagement:
fork: true -- 后台守护进程模式
pidFilePath: <string> -- pid文件位置,一般不用设置,默认在data目录下
net:
bindIp: <IP> -- 监听地址
port: 27017 -- 端口号,不配置默认端口号是27017
security:
authorization: enabled -- 是否打开用户名密码验证
MongoDB后台管理shell
执行 mongo 二进制文件,即可以进入 MongoDB 的管理后台Shell,类似于mysql 的客户端,可以执行mongo命令。进入之后,默认连接到 test 数据库。
[mongod@web01 ~]$ mongo
MongoDB shell version v4.2.17
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("d5be2e3f-e3a2-4cf5-b65f-f624944cead3") }
MongoDB server version: 4.2.17
......
> > db
test
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
如果 MongoDB 启动监听了特定的IP和端口,那么进入后台shell使用 mongo IP:端口
$ mongo 192.168.5.50:27017
3 MongoDB基本操作
MongoDB默认存在三个库
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
- admin库:系统预留库,MongoDB系统管理库
- local库:本地预留库,存储关键的日志
- config库:MongoDB配置信息库
基本命令
# 查看所有数据库
show databases
show dbs
# 查看某个库里的所有集合(表)
show tables
show collections
# 使用数据库
use admin
#查看当前所在的数据库
db
MongoDB中不需要创建库和表,在使用的时候即用即创建。创建表也不需要定义表结构,只要输入表名即可。
# 创建数据库
> use syushin
switched to db syushin
# 创建集合
> db.createCollection('student')
{ "ok" : 1 }
# 查看集合
> show collections;
student
插入数据
#返回1表示插入成功
> db.student.insert({name: 'Tom', age: 25})
WriteResult({ "nInserted" : 1 })
# 如果一个表没有创建,直接插入也是可以插入成功的,即用即创建
> db.student2.insert({name: 'Tom', age: 25})
WriteResult({ "nInserted" : 1 })
# 插入多一列也可以直接插入
> db.student.insert({id: 1,name: 'Tom',age: 25})
WriteResult({ "nInserted" : 1 })
# 支持for循环,批量插入数据
> for(i=0;i<10000;i++){db.log.insert({"uid": i,"name": "mongodb","age": 18,"date": new Date()})}
WriteResult({ "nInserted" : 1 })
简单的查询
# 查询数据表的所有行数
> db.log.count()
10000
# 查询所有,相当于select * from 表,默认分页显示20条数据,按it显示下一页
> db.log.find()
......
Type "it" for more
# 设置分页显示50条数据
> DBQuery.shellBatchSize=50
50
# 按条件查询
> db.log.find({"uid":100})
{ "_id" : ObjectId("619ddb0aa034fd5eb978b589"), "uid" : 100, "name" : "mongodb", "age" : 18, "date" : ISODate("2021-11-24T06:26:18.148Z") }
# 以标准json格式显示数据
> db.log.find({"uid":100}).pretty()
{
"_id" : ObjectId("619ddb0aa034fd5eb978b589"),
"uid" : 100,
"name" : "mongodb",
"age" : 18,
"date" : ISODate("2021-11-24T06:26:18.148Z")
}
简单的删除数据
# 删除一条匹配的数据
> db.log.remove({'uid':100})
WriteResult({ "nRemoved" : 1 })
# 删除所有数据
> db.log.remove({})
WriteResult({ "nRemoved" : 9999 })
查看集合中数据的总大小(以字节为单位)加上集合中每个索引的大小。
> db.log.totalSize()
282624
4 MongoDB用户管理
MongoDB数据库默认是没有用户名和密码的,即无权限访问限制。为了方便数据库的管理和安全,需创建数据库用户。说明:
验证库: 建立用户时use到的库,在使用用户时,要加上验证库才能登陆。
对于管理员用户,必须在admin下创建.
1. 建用户时,use到的库,就是此用户的验证库
2. 登录时,必须明确指定验证库才能登录
3. 通常,管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库
4. 如果直接登录到数据库,不进行use,默认的验证库是test,不是我们生产建议的.
5. 从3.6 版本开始,不添加bindIp参数,默认不让远程登录,只能本地管理员登录。
用户权限
权限 | 说明 |
---|---|
Read | 允许用户读取指定数据库 |
readWrite | 允许用户读写指定数据库 |
dbAdmin | 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile |
userAdmin | 允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户 |
clusterAdmin | 只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。 |
readAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读权限 |
readWriteAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读写权限 |
userAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的userAdmin权限 |
dbAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。 |
root | 只在admin数据库中可用。超级账号,超级权限 |
用户创建语法
> use admin
> db.createUser
{
user: "<name>",
pwd: "<cleartext password>",
roles: [
{ role: "<role>",
db: "<database>" } | "<role>",
...
]
}
语法说明:
- user:用户名
- pwd:用户密码
- roles:指定用户的角色,可以用一个空数组给新用户设定一个空角色
- db:作用对象
示例,创建超级管理员root
> use admin
switched to db admin
> db.createUser(
{
user: 'root',
pwd: '123qwe',
roles: [{role: 'root', db: 'admin'}],
})
创建完成之后,使用下面命令验证用户是否可用。
> db.auth('root','123qwe')
1
然后在配置文件中,开启mongo的验证功能,编辑配置文件 /mongodb/conf/mongo.conf
,加入以下配置:
security:
authorization: enabled
重启mongodb
$ mongod -f /mongodb/conf/mongo.conf --shutdown
$ mongod -f /mongodb/conf/mongo.conf
登录验证:
[mongod@web01 conf]$ mongo
MongoDB shell version v4.2.17
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("84e20c65-0d4e-4ae5-b2d8-7a5498faaada") }
MongoDB server version: 4.2.17
# 没验证之前,查数据库为空
> show dbs
# 切换到验证库
> use admin
switched to db admin
# 没验证前,查看表报错
> show tables
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus
# 进行验证
> db.auth("root", "123qwe")
1
# 验证后正确查表
> show tables
system.users
system.version
>
命令行进入mongo的后台shell时,可进行验证:
# 本地登录
$ mongo -uroot -p123qwe admin
......
> db
admin
> show tables
system.users
system.version
# 远程登录
$ mongo -uroot -p123qwe 192.168.5.50/admin
查看创建的用户:
> db.system.users.find().pretty()
{
"_id" : "admin.root",
"userId" : UUID("2be69119-69e2-4e00-9681-29a4734a7c38"),
"user" : "root",
"db" : "admin",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "f98FyiyJF1PpeZswg+HM6g==",
"storedKey" : "/iu5Z9bgDlty6G6dRpG4Na804aM=",
"serverKey" : "z5/SCZpqodYrCQgXzl+NB6f6eS4="
},
"SCRAM-SHA-256" : {
"iterationCount" : 15000,
"salt" : "2xJUCbrH1hZlUCOnkDckijE8hTBgrBdIQ01BEw==",
"storedKey" : "yxukPbFfEIsChsMi+5rdqTL3YTsRKLD59AEYm8ZUlCI=",
"serverKey" : "pqXoB5iGYK8kB5nDQ4TOzjWhF50Qwy0hE6fLaVnnQ3U="
}
},
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
示例:创建应用用户
创建对 test1 库只有只读权限的用户
# 切换到test1库
> use test1
switched to db test1
# 创建用户
> db.createUser(
{
user: 'test1',
pwd: 'test1',
roles: [{role: 'read', db: 'test1'}],
})
# 验证,先插入一条数据
> db.stu.insert({'name': 'laowang'})
WriteResult({ "nInserted" : 1 })
# 使用test1用户登录
$ mongo -utest1 -ptest1 192.168.5.50/test1
# 查询数据成功
> db.stu.find()
{ "_id" : ObjectId("619df123dd5f8d18a46d9f0b"), "name" : "laowang" }
# 插入数据失败,说明权限配置成功
> db.stu.insert("name": 'lisi')
2021-11-24T16:02:48.864+0800 E QUERY [js] uncaught exception: SyntaxError: missing ) after argument list :
@(shell):1:20
创建对 test2 库具有读写权限的用户
> use test2
switched to db test2
> db.createUser(
{
user: 'test2',
pwd: 'test2',
roles: [{role: 'readWrite', db: 'test2'}],
})
创建test3用户,对test1有只读权限,对test2库有读写权限
> use test1
switched to db test1
> db.createUser(
... {
... user: 'test3',
... pwd: 'test3',
... roles: [{role: 'read', db:'test1'},{role: 'readWrite',db: 'test2'}],
... })