MongoDB逻辑存储结构:
SQL术语/概念 MongoDB 术语/概念 解释/说明
database database 数据库
table collection 数据表 / 集合
row document 数据记录行 / 文档
column field 数据字段 / 域
index index 索引
table joins 表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键
1.数据库(database)
一个MongoDB中可以建立多个数据库,MongoDB的默认数据库为test,该数据库存储在data目录中,要想显示它,需要向数据库中插入数据。
不同的数据库放置在不同的文件中。
特殊的数据库:
admin:
从权限角度看,这是root数据库。如果将一个用户加入此数据库,这个用户将自动继承所有数据库的权限,一些特定的服务端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器
local:
这个数据库永远不会被复制,可以用来存储仅限于本地单台服务器的任意集合
config:
当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息
2.集合(collection)
(1.)集合就是MongoDB文档组,类似于关系型数据库管理系统(Relational Database Managerment System,RDBMS)中的表格
(2.)集合存在于数据库中,没有固定的结构,这就意味着集合中可以插入不同格式和类型的数据
> use local
switched to db local
> show collections
startup_log
system.indexes
> show tables;
startup_log
system.indexes
(3.)当第一个文档插入时,集合就会被创建
(4.)合法的字符集名不能是空字符串"",不能包含\0字符(空字符),这个字符表示集合名的结尾,不能以"system."开头,这是为系统集合保留的前缀
3.文档(document)
(1.)文档是一个键值(key-value)对,即BSON
(2.)MongoDB的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型
注意:
first:文档中的键值对是有序的
second:文档中的值可以是双引号里面的字符串,也可以是其他几种数据类型(甚至可以是整个嵌入的文档)
third:MongoDB区分类型和大小写
fourth:MongoDB文档中不能有重复的键
fifth:文档的键是字符串,除了少数例外情况,键可以使用任意UTF-8字符
文档命名规范:
(1.)键不能含有\0(空字符),这个字符用来表示键的结尾
(2.).和$有特别的意义,只有在特定环境下才能使用
(3.)以下划线"_"开头的键是保留的(不是严格要求)
示例向集合添加文档:
> use pdd # 创建并使用pdd数据库
switched to db pdd
> db.users.insert({"id":1,"name":"Tome"}); # 向pdd数据库的users集合添加一行数据
WriteResult({ "nInserted" : 1 })
> show collections # 显示数据库中的所有命令
system.indexes
users
> db.users.insert({"id":2,"name":"Jerry","isadmin":true,"gender":null,"favorite":["apple","banana","orange",1,2,3],"regtime":new Date()});
WriteResult({ "nInserted" : 1 })
> db.users.find(); # 显示users集合中的所有文档
{ "_id" : ObjectId("5f062e53687d86057d606c49"), "id" : 1, "name" : "Tome" }
{ "_id" : ObjectId("5f062ee7687d86057d606c4a"), "id" : 2, "name" : "Jerry", "isadmin" : "true", "gender" : null, "favorite" : [ "apple", "banana", "orange", 1, 2, 3 ], "regtime" : ISODate("2020-07-08T20:39:03.425Z") }
MongoDB物理存储结构:
MongoDB物理存储结构主要包括数据存储和日志存储
数据存储:
MongoDB的数据目录由配置文件中的dbpath指定,这里为/data/mongodb1/,用来存储所有的MongoDB的数据文件
[root@localhost bin]# ls -lh /data/mongodb1/
total 161M
-rw-------. 1 root root 64M Jul 7 10:53 admin.0
-rw-------. 1 root root 16M Jul 7 10:53 admin.ns
drwxr-xr-x. 2 root root 197 Jul 7 22:21 diagnostic.data
drwxr-xr-x. 2 root root 18 Jul 7 22:09 journal
-rw-------. 1 root root 64M Jul 7 22:09 local.0
-rw-------. 1 root root 16M Jul 7 22:09 local.ns
-rw-r--r--. 1 root root 5 Jul 7 22:09 mongod.lock
-rw-r--r--. 1 root root 69 Jul 7 10:53 storage.bson
每张表对应一个命令空间,每个索引也有对应的命名空间,而这些命名空间的元数据都放在.ns文件中
日志存储:
日志存储结构:
1.系统日志文件的存放由配置文件中的logpath指定,这里为/data/logs/mongodb/
2.Journal日志文件,用于MongoDB崩溃恢复的保障
3.oplog复制操作日志文件在启动主从复制时出现
4.慢查询日志文件,需要在配置文件中指定profile=1(开启慢查询)与slowms=200(记录毫秒数),查看慢查询的命令为:>db.system.profile.find()。
MongoDB数据类型:
String:字符串
Integer:整型数值
Boolean:布尔值
Double:双精度浮点值
Arrays:用于将数组或列表或多个值存储为一个键
Object:用于内嵌文档
Null:用于创建空值
Date:日期时间
Binary Data:二进制数据
示例:
如何查看MongoDB的数据类型
> a=db.users.findOne({"id":2});
{
"_id" : ObjectId("5f062ee7687d86057d606c4a"),
"id" : 2,
"name" : "Jerry",
"isadmin" : true,
"gender" : null,
"favorite" : [
"apple",
"banana",
"orange",
1,
2,
3
],
"regtime" : ISODate("2020-07-08T20:39:03.425Z")
}
> typeof(a.id)
number
> typeof(a.name)
string
> typeof(a.isadmin)
boolean
> typeof(a.gender)
object
> typeof(a.favorite)
object
> typeof(a.regtime)
object
MongoDB基本操作:
1.基础命令:
show dbs:查看当前实例下的数据库列表
show users:显示用户
use <db_name>:切换当前数据库
db.help():显示数据库操作命令
show collections:显示当前数据库中的集合
db.foo.help():显示集合操作命令,foo是当前数据库下的集合
db.foo.find():对当前数据库中foo集合进行数据查找
2.在MongoDB中创建和删除数据库
创建数据库:
use DATABASE_NAME # 如果数据库不存在,则创建数据库,否则切换到指定数据库
示例:
> use aaa; # 创建数据库aaa
switched to db aaa
> show dbs; # 查看当前存在的数据库,新建的数据库未插入数据则不显示
admin 0.078GB
kgc 0.078GB
local 0.078GB
>
> db.users.insert({"id":1,"name":"zhangsan"}); # 插入测试数据
WriteResult({ "nInserted" : 1 })
>
> show dbs # 再次查看
aaa 0.078GB
admin 0.078GB
kgc 0.078GB
local 0.078GB
>
> db.dropDatabase(); # 删除数据库aaa
{ "dropped" : "aaa", "ok" : 1 }
>
> show dbs; # 验证是否删除成功
admin 0.078GB
kgc 0.078GB
local 0.078GB
>
3.MongoDB的集合和文档操作
存储在MongoDB的集合中的所有数据都是Binary JSON格式,简称BSON,BSON是一种类似于JSON的二进制形式的存储格式
使用insert()方法向集合中插入文档
语法:
db.COLLECTION_NAME.insert(document)
使用update()方法来更新集合中的文档
语法:
db.COLLECTION_NAME.update(condition)
使用remove()方法移除集合中的数据
语法:
db.COLLECTION_NAME.remove(condition)
使用drop()方法删除集合
语法:
db.COLLECTION_NAME.drop()
示例:
> use kgc
switched to db kgc
> show collections
system.indexes
users
> db.users.find() # 查看users集合中的数据
{ "_id" : ObjectId("5f062e53687d86057d606c49"), "id" : 1, "name" : "Tome" }
{ "_id" : ObjectId("5f062ee7687d86057d606c4a"), "id" : 2, "name" : "Jerry", "isadmin" : "true", "gender" : null, "favorite" : [ "apple", "banana", "orange", 1, 2, 3 ], "regtime" : ISODate("2020-07-08T20:39:03.425Z") }
>
> db.users.update({"id":1},{$set:{"name":"Bob"}}); # 更新id为1的数据的姓名为Bob
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>
> db.users.find(); # 查看更新成功
{ "_id" : ObjectId("5f062e53687d86057d606c49"), "id" : 1, "name" : "Bob" }
{ "_id" : ObjectId("5f062ee7687d86057d606c4a"), "id" : 2, "name" : "Jerry", "isadmin" : "true", "gender" : null, "favorite" : [ "apple", "banana", "orange", 1, 2, 3 ], "regtime" : ISODate("2020-07-08T20:39:03.425Z") }
>
> db.users.remove({"id":1}); # 删除id为1的数据
WriteResult({ "nRemoved" : 1 })
>
> db.users.find() # 验证
{ "_id" : ObjectId("5f062ee7687d86057d606c4a"), "id" : 2, "name" : "Jerry", "isadmin" : "true", "gender" : null, "favorite" : [ "apple", "banana", "orange", 1, 2, 3 ], "regtime" : ISODate("2020-07-08T20:39:03.425Z") }
>
> db.users.drop() # 删除users集合
true
> show collections;
system.indexes
>
MongoDB日常维护:
1.备份与恢复管理:
(1.)导入导出
使用mongoimport和mongoexport来导入和导出MongoDB中的数据
示例:
> for(var i=1;i<=1000;i++)db.users.insert({"id":i,"name":"JackyALice"})
WriteResult({ "nInserted" : 1 })
> db.users.count()
1000
> exit
bye
[root@localhost ~]# mongoexport -d kgc -c users -o ./users.json
2020-07-09T05:33:12.275+0800 connected to: localhost
2020-07-09T05:33:12.294+0800 exported 1000 records
[root@bogon ~]# head -n3 users.json
{"_id":{"$oid":"5f063b0f687d86057d606c4c"},"id":1.0,"name":"JackyALice"}
{"_id":{"$oid":"5f063b0f687d86057d606c4d"},"id":2.0,"name":"JackyALice"}
{"_id":{"$oid":"5f063b0f687d86057d606c4e"},"id":3.0,"name":"JackyALice"}
[root@bogon ~]# mongoimport -d kgc -c users1 --file users.json
2020-07-09T05:34:41.655+0800 connected to: localhost
2020-07-09T05:34:41.664+0800 imported 1000 documents
[root@bogon ~]# mongo
> use kgc
switched to db kgc
> show collections
system.indexes
users
users1
> exit
bye
[root@bogon ~]# mongoexport -d kgc -c users1 -q ‘{"id":{"$gt":500}}‘ -o users2.json
2020-07-09T05:37:37.578+0800 connected to: localhost
2020-07-09T05:37:37.583+0800 exported 500 records
[root@bogon ~]# head -n3 users2.json
{"_id":{"$oid":"5f063b0f687d86057d606e40"},"id":501.0,"name":"JackyALice"}
{"_id":{"$oid":"5f063b0f687d86057d606e41"},"id":502.0,"name":"JackyALice"}
{"_id":{"$oid":"5f063b0f687d86057d606e42"},"id":503.0,"name":"JackyALice"}
参数说明:
-d:指明数据库的名字
-c:指明collection的名字
-f:指明要导出哪些列
-o:指明要导出的文件名
-q:指明导出数据的过滤条件
注:更多的参数可以通过--help命令来查看
(2.)备份与恢复
mongodump命令脚本语法格式:
>mongodump -h dbhost -d dbname -o dbdirectory
参数说明:
-h:MongoDB所在的服务器地址,例如:127.0.0.1,指定端口:127.0.0.1:27017
-d:需要备份的数据库实例
-o:备份的数据存放的位置,该目录需要提前创建,备份完成后,系统自动在dump目录下创建一个对应数据库名称的目录,这个目录里面存放数据库实例的备份数据
示例:
[root@localhost ~]# mkdir backup
[root@localhost ~]# cd backup/
[root@localhost backup]#
[root@localhost backup]# mongodump -d kgc -o .
2020-07-09T16:31:49.320+0800 writing kgc.users1 to
2020-07-09T16:31:49.320+0800 writing kgc.users to
2020-07-09T16:31:49.324+0800 done dumping kgc.users (999 documents)
2020-07-09T16:31:49.324+0800 done dumping kgc.users1 (1000 documents)
[root@localhost backup]# ls
kgc
[root@localhost backup]# cd kgc/
[root@localhost kgc]# ls
users1.bson users1.metadata.json users.bson users.metadata.json
[root@localhost kgc]#
mongorestore命令脚本语法格式:
>mongorestore -h dbhost -d dbname --directoryperdb dbdirectory
参数说明:
--directory:可简写为--dir
其余参数含义与mongodump一致,参考上面
示例:
mongorestart -d kgc1 --dir=./backup/kgc/
(3.)复制数据库
使用db.copyDatabase()命令来复制数据库
格式:
db.copyDatabase(fromdb,todb,fromhost)
示例:
> show dbs;
admin 0.078GB
kgc 0.078GB
local 0.078GB
>
> db.copyDatabase("kgc","pdd","localhost")
{ "ok" : 1 }
>
> show dbs;
admin 0.078GB
kgc 0.078GB
local 0.078GB
pdd 0.078GB
>
(4.)克隆集合:
[root@localhost backup]# mongod -f /usr/local/mongodb/bin/mongodb2.conf
about to fork child process, waiting until server is ready for connections.
forked process: 4057
child process started successfully, parent exiting
[root@localhost ~]#
[root@localhost ~]# netstat -anpt | grep mongod
tcp 0 0 0.0.0.0:27018 0.0.0.0:* LISTEN 4057/mongod
tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 3349/mongod
[root@localhost ~]# mongo --port 27018
>
> show dbs;
admin 0.078GB
local 0.078GB
>
> db.runCommand({"cloneCollection":"kgc.users1","from":"localhost:27017"})
{ "ok" : 1 }
>
> show dbs;
admin 0.078GB
kgc 0.078GB
local 0.078GB
>
> use kgc
switched to db kgc
>
> show collections
system.indexes
users1
>
2.安全管理
MongoDB安全管理主要包括MongoDB的安全访问控制和用户权限分配
(1.)限制监听特定IP和端口
只绑定内网卡地址:bind_ip=192.168.1.101
只侦听指定的端口:port=27017
(2.)授权启动
[root@localhost ~]# mongo --host 192.168.1.101
> use admin
switched to db admin
>
> db.createUser({"user":"root","pwd":"123","roles":["root"]}) # 创建一个用户名为root,密码为123,角色为管理员(root)
Successfully added user: { "user" : "root", "roles" : [ "root" ] }
>
> exit
bye
[root@localhost ~]# vim /usr/local/mongodb/bin/mongodb1.conf
添加:
auth=true
[root@localhost ~]#
[root@localhost ~]# ps -aux | grep mongod
root 5097 0.5 6.2 1596560 116864 ? SLl 17:41 0:01 mongod -f /usr/local/mongodb/bin/mongodb1.conf
root 5239 0.0 0.0 112648 960 pts/0 S+ 17:44 0:00 grep --color=auto mongod
[root@localhost ~]# kill -9 5097
[root@localhost ~]# ps -aux | grep mongod
root 5247 0.0 0.0 112648 960 pts/0 S+ 17:44 0:00 grep --color=auto mongod
[root@localhost ~]# mongod -f /usr/local/mongodb/bin/mongodb1.conf
about to fork child process, waiting until server is ready for connections.
forked process: 5265
child process started successfully, parent exiting
[root@localhost ~]# mongo --host 192.168.1.101
MongoDB shell version v3.4.24
connecting to: mongodb://192.168.1.101:27017/
MongoDB server version: 3.4.24
>
> show dbs;
2020-07-09T17:45:27.750+0800 E QUERY [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
"code" : 13,
"codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:814:19
shellHelper@src/mongo/shell/utils.js:704:15
@(shellhelp2):1:1
> use admin
switched to db admin
> db.auth("root","123")
1
> show dbs
admin 0.078GB
kgc 0.078GB
local 0.078GB
pdd 0.078GB
3.MongoDB监控
(1.)查看数据库统计信息的命令:
查看数据库实例的状态信息:
db.serverStatus()
查看当前数据库的统计信息:
db.stats()
(2.)通过web界面查看系统监控信息,需要在配置文件中添加下面一行
httpinterface=true
在浏览器中通过http://localhost:28017进行访问
(3.)查看集合统计信息的命令
查看集合统计信息:
db.users.stats()
查看集合大小:
db.users.dataSize()
(4.)第三方监控工具
可以再Nagios中配置使用MongoDB插件来监控MongoDB数据库