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中表的概念换成了集合,数据的概念换成了文档
一、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进行网页访问