MongoDB数据库

什么是MongoDB?

MongoDB是一款C语言开源开发的,跨平台,面向文档的NoSQL数据库

什么是NoSQL?

存储数据不以关系模型为依据,不需要固定的表格式。非关系型数据库作为关系型数据库的一个补充,在日益快速发展的网站时代,发挥着高效与高性能,NoSQL用于超大规模数据的存储 常用的非关系型数据库:MongoDB、Memcache、Redis、HBase 非关系型数据库的优点: - 数据库高并发读写的需求 - 对海量数据高效率存储与访问 - 数据库的高扩展与高可用

MangoDB的定义

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的
为 Web 应用提供可扩展的高性能数据存储解决方案,主要适用于网站数据、数据缓存、分布式场景和JSON文档格式存储,适合大数据量,高并发、弱事务的互联网应用上

MongoDB的优缺点
优点:高可扩展性、分布式计算、低成本、架构的灵活性,半结构化数据、没有复杂的关系
MongoDB提供了复制、高可用性和自动分片功能,支持丰富的查询表达式,支持各种编程语言,比如RUBY,PYTHON,JAVA,C++,PHP,C#等
缺点:没有标准化、有限的查询功能

MongoDB运行的两大概念:集合(collection)和文档(document)
在MongoDB中表的概念换成了集合,数据的概念换成了文档

TOC

一、MongDB数据库安装

★准备工作★

安装包:mongodb-linux-x86_64-rhel70-4.0.28.tgz
mongodb下载地址:
https://www.mongodb.com/try/download/community

安装配置

1.下载安装依赖包和MongoDB安装包

yum -y install openssl-devel
tar zxf mongodb-linux-x86_64-rhel70-4.0.28.tgz
mv mongodb-linux-x86_64-rhel70-4.0.28 /mongodb

2.创建MongoDB的数据存储、日志、pid文件和配置文件存放等目录以及日志文件

mkdir -p /mongodb/{data,logs,run,conf}
touch /mongodb/logs/mongo.log

3.创建MangoDB配置文件和设置启动参数

vim /mongodb/conf/mongo.conf
------------------------------------
#端口号
port=27017
#ip地址
bind_ip=0.0.0.0
#数据存储目录
dbpath=/mongodb/data
#日志文件路径
logpath=/mongodb/logs/mongo.log
#使用追加的方式写日志
logappend=true
#指定pid路径
pidfilepath=/mongodb/run/mongo.pid
#后台运行
fork=true
#最大连接数,默认是2000
maxConns=5000
#指定存储引擎为内存映射文件
storageEngine=mmapv1

或者另外一种格式

-----------------------------------
#### mongodb datadir
storage:
  dbPath: /mongodb/data
  journal:
    enabled: true
  engine: wiredTiger
storage.wiredTiger.engineConfig.cacheSizeGB: 2
#### mongodb log
systemLog:
  destination: file
  logAppend: true
  path: /mongodb/logs/mongo.log
 # timeStampFormat: iso8601-utc
#### mongodb PID
processManagement:
  fork: true
  pidFilePath: /mongodb/run/mongo.pid
#### mongodb network
net:
  port: 27017
  bindIp: 0.0.0.0
#### mongodb auth
security:
#  keyFile: /mongodb/run/mongodb-keyfile
#  clusterAuthMode: keyFile
  authorization: enabled

4.启动和停止mongodb实例

[root@feili12138 ~]# /mongodb/bin/mongod -f /mongodb/conf/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 31151
child process started successfully, parent exiting
[root@feili12138 ~]# /mongodb/bin/mongod -f /mongodb/conf/mongod.conf --shutdown
killing process with pid: 31151

性能调优

当MongDB处于频繁访问状态,如果shell启动进程所占用的资源设置过低,将会产生错误导致无法连接MongoDB,需要设置
Linux系统默认一个进程最大文件打开数目为1024,有时,这些限制的默认值太小,这会导致正常MongoDB操作过程中出现一系列问题

ulimit -u 25000(单个进程文件打开数)
ulimit -n 25000(可打开的进程/线程)

设置内核参数

echo "0" > /proc/sys/vm/zone_reclaim_mode
sysctl -w vm.zone_reclaim_mode=0
echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
echo "never" > /sys/kernel/mm/transparent_hugepage/defrag

MongoDB多实例

创建MongoDB新的数据存储目/mongodb/data2,日志文件

mkdir /mongodb/data2
touch /mongodb/logs/mongo2.log

在存放主配置文件的目录创建新主配置文件,内容对比第一个实例的配置文件修改下面参数即可(需要创建几个实例就复制编辑几个,名字、端口、数据存储路径、日志文件、pid文件不同)

vim /mongodb/conf/mongo2.conf
-----------------------------------
port=27018
dbpath=/mongodb/data2
logpath=/mongodb/logs/mongo2.log
pidfilepath=/mongodb/run/mongo2.pid

启动新建的实例(启动方式跟第一个实例一样,只是指定配置文件不同)

/mongodb/bin/mongod -f /mongodb/conf/mongo2.conf

二、MongoDB语法基础

登录操作

登录命令:mongo
–host:指定地址,默认127.0.0.1
–port:指定端口,默认27017
-u:指定登录用户
-p:指定登录密码
例如:

mongo --host hostname --port 27017 -uusername -p'password'
#或者第二种登录命令格式
mongo hostname:port/db_name -u username -p 'password'

基础操作

#切换数据库
use db_name
#查看用户
show users
#查看存在的数据库
show databases
#查看数据库操作命令
db.help()
#查看存在的集合
show collections
#查看集合操作命令
db.collection_name.help()
#查看集合索引
db.collection_name.getIndexes()

增添操作

创建数据库和集合
如果数据库不存在,则创建数据库,创建集合则会创建新的数据库,否则切换到指定数据库

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
> use mytest
switched to db mytest
> db.createCollection("collection1")
{ "ok" : 1 }
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
mytest  0.000GB

插入数据
MongoDB 使用 insert() 或 save() 方法向集合中插入文档,如果该集合不存在, 则会自动创建该集合并插入文档
insert()和save()的区别:

  • save()如果原来的对象不存在,那么都会向collection里插入数据,如果存在该对象,save()会调用update更新数据,而insert()会忽略操作
  • insert()一次性插入一个列表,效率高, save()需要遍历列表,一个个插入,效率低
db.collection_name.insert(document)
db.collection_name.save(document)

直接插入数据:

db.collection1.insert({
        title: '七年级',
        description: '七年级是关键的一年',
        by: 'admin',
        tags: ['张三', '男', '18岁'],
        likes: 100
  })

定义变量再插入数据:

document = ({
        title: '七年级',
        description: '七年级是关键的一年',
        by: 'admin',
        tags: ['张三', '男', '18岁'],
        likes: 100
  })

db.collection2.insert(document)

循环插入:

for(var i=0;i<10000;i++)
{
db.collection3.insert({name:"caonima",age:i})
}

删除操作

删除库
删除数据库库,先进入数据库再执行删除语句

use db_name
db.dropDatabase()

remove() 是用来删除集合中的数据,在删除之前会先执行 find() 命令来判断执行的条件是否正确

db.collection_name.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)

query :(可选)删除的文档的条件
justOne : (可选)如果设为 true 或 1,则只删除一个文档
writeConcern :(可选)抛出异常的级别
删除集合

db.collection_name.drop()

删除集合中的所有文档

db.collection_name.remove({})

条件删除文档

#删除集合中的所有文档
db.collection1.remove({})
#删除集合中的第一个文档
db.collection1.remove({},1)
#删除title为张三的文档
db.collection1.remove({'title':'张三'}, 1)

修改操作

update()用于更新已存在的文档

db.collection_name.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

query : update 的查询条件,类似sql update查询内where后面的
update : update的对象和一些更新的操作符(如,inc…)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在 update 的记录,是否插入记录,true 为插入,默认是 false,不插入
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
writeConcern :可选,抛出异常的级别
修改第一条发现的文档
$set 为部分更新操作符,只会更新 $set 之后的数据,并不会覆盖之前的数据

db.collection1.update({ 'title': '七年级' }, { $set: { 'title': '八年级' } })

修改多条发现相同的文档
需要设置 multi 参数为 true

db.collection1.update({ 'title': '七年级' }, { $set: { 'title': '八年级' } }, { multi: true })

通过save()修改数据
是根据ID去相同去进行更新操作

document = ({
    "_id" : ObjectId("61a6e084e9589b7c41110da4"),
    title: '七年级',
    description: '七年级应该开心玩耍',
    by: 'admin',
    tags: ['张五', '男', '18岁'],
    likes: 100
})

db.collection1.save(document)

查询操作

通过find()来查询

db.collection.find(query, projection)

query:查询条件,类似于SQL中的WHERE部分
projection:可选,使用投影操作符指定返回的键
查询集合所有文档

db.collection_name.find()

使用pretty()格式化输出

db.collection_name.find().pretty()

单个文档查询
使用findOne()来查询

db.collection_name.findOne()

指定查询的条数
使用limit()来限定

db.collection_name.find().limit(10)

统计查询的条数
使用count()来统计

db.collection_name.find().count()

查询结果排序显示
sort()可以对查询结果拍寻,通过1和-1来指定排序的方式,1为升序排列,-1是用于降序排列

db.collection_name.find().pretty().sort({'_id':1})

三、MongoDB备份和恢复

mongodump和mongorestore

mongodump备份
-h:MongoDB所在的服务器IP地址(可以在后面加指定端口号)
–port:指定端口号
-u:指定用户
-p:指定用户的密码
-d:指定需要备份的数据库
-c:指定需要备份的集合
-o:指定备份的数据库存放的位置(该目录要提前创建好,备份数据会存放在该目录下自动创建的test目录下)
例如:

mongodump -h hostname --port 27017 -u xxxx –p’xxxxx’ -u xxxx –p’xxxxx’ -d db_name -c collection_name -o dirpath

mongorestore恢复
–dir:指定恢复数据存储的数据文件位置,可以指定目录或者文件
例如:

mongorestore -h hostname --port 27017 -u xxxx –p’xxxxx’ -d db_name --dir dirpath

mongoexport和mongoimport

MongoDB中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件

mongoexport -d dbname -c collectionname -o filepath --type json/csv -f field

数据导入工具:mongoimport

mongoimport -d dbname -c collectionname --filepath filename --type json/csv -f field

-d:指定数据库名
-c:指定collection集合名
-f:指定导出哪些列
-o:指定要导出的文件名
-q:指定导出数据的过滤条件
注意:在MySQL导入的时候,之前MySQL导出的时候加个database的选项,导入的时候就可以不用创建

四、MongoDB存储结构

逻辑结构主要由集合(collection)、文档(Document)、数据库(database) 三个部分组成,其中文档是核心概念,它是MongoDB逻辑存储最小的存储单元
★集合:
合法的集合名:

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
  • 集合名不能以"system."开头,这是为系统集合保留的前缀。
  • 用户创建的集合名字不能含有保留字符,有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的 集合中包含该字符,除非你要访问这种系统创建的集合,否则千万不要在名字里出现$

★文档:
文档是一组键值(key-value)对(即BSON),MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点
需要注意的是:

  • 文档中的键/值对是有序的
  • 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)
  • MongoDB区分类型和大小写
  • MongoDB的文档不能有重复的键
  • 文档的键是字符串,除了少数例外情况,键可以使用任意UTF-8字符

物理存储结构:
数据存储结构:命名空间文件(.ns结尾文件) 数据文件(.0,1,2,3…)
日志存储结构:journal日志文件:用于MongDB崩溃恢复的保障
oplog复制操作日志文件:只有在主从复制开启之后才会出现
慢查询日志:需要开启后才可以

★数据库:
初始内建数据库:admin:admin库主要存放有数据库帐号相关信息。
local:local数据库永远不会被复制到从节点,可以用来存储限于本地单台服务器的任意集合
config:config数据库用于分片集群环境,存放了分片相关的元数据信息。
test:MongoDB默认创建的一个测试库

MongoDB数据类型
String:字符串,存储数据常用的数据类型,在 MongoDB 中,UTF-8 编码的字符串才是合法的
Integer:整型数值,用于存储数值,根据你所采用的服务器,可分为 32 位或 64 位
Boolean:布尔值,用于存储布尔值(真/假)
Double:双精度浮点值,用于存储浮点值
Min/Max keys:将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比
Array:用于将数组或列表或多个值存储为一个键
Timestamp:时间戳,记录文档修改或添加的具体时间
Object:用于内嵌文档
Null:用于创建空值
Symbol:符号,该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言
Date:日期时间,用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息
Object ID:对象 ID,用于创建文档的 ID
Binary Date:二进制数据,用于存储二进制数据
Code:代码类型,用于在文档中存储 JavaScript 代码
Regular expression:正则表达式类型。用于存储正则表达式

五、MongoDB管理

限制监听的IP地址和端口(在配置文件中设置)

vim /mongodb/conf/mongo.conf
--------------------------------------------
bind_ip=192.168.31.101  #只允许这个IP地址进行访问
port = 27018  #只允许这个端口号进行访问

授权启动登录userAdminAnyDatabase(MongoDB第一次默认不需要密码,也没有任何用户)
1.登录进入数据库,切换到admin库

use admin

2.创建管理用户

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

roles:指定用户的角色,可以用一个空数组给新用户设定空角色,在roles字段,可以指定内置角色和用户定义的角色
Built-In Roles(内置角色):
数据库用户角色:read、readWrite;
数据库管理角色:dbAdmin、dbOwner、userAdmin
集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager
备份恢复角色:backup、restore
所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
超级用户角色:root  
补充: 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
内部角色:__system
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限
3.启动用户验证功能

/mongodb/bin/mongod -f /mongodb/conf/mongo.conf --auth

或者编辑配置文件:

vim /usr/local/mongodb/conf/mongodb.conf
------------------------------------------
auth = true

查看已有用户

show users
#或者
db.system.users.find()

4.登录MongoDB,使用admin用户对admin库进行验证登录

use admin
db.auth("admin","123456")

使用管理用户的用户admin 来创建其他数据库的用户名和密码

use test
db.createUser({user:"testuser",pwd:"123456",roles:[{role:"readWrite",db:"test"}]})

更新用户

db.updateUser('testuser',{pwd:"111111",roles:[{role:"readWrite",db:"test"}]})

删除用户

db.dropUser("testuser")

注意:使用有管理用户的权限的用户admin登陆之后才能删除用户
进程管理

#查询正在执行的操作进程
db.currentOp()
#终止进程
db.killOp("shard3:466404288")

MongoDB监控
1.数据库命令查看

#查看数据库实例状态信息
db.serverStatus()
#查看当前数据库的统计信息
db.stats()
#查看集合统计信息
db.users.stats()
#查看集合大小
db.users.dataSize()

2.通过网页来进行监控(编辑配置文件)

vim /mongodb/conf/mongo.conf
-----------------------------
httpinterface=true

通过http://localhost:27018进行网页访问