常见数据库管理系统
常见的数据库管理系统,及其排名情况如下:
图 - 数据库管理系统使用情况世界排名
数据来源:https://db-engines.com/en/ranking
NoSQL是对不同于传统的关系数据库的数据库管理系统的统称。
NoSQL最重要的是不使用SQL作为查询语言。其数据存储可以不需要固定的表格模式,也经常会避免使用SQL的JOIN操作,一般有水平可扩展性的特征。
NoSQL一词最早出现于1998年,是Carlo Strozzi开发的一个轻量、开源、不提供SQL功能的关系数据库。
2009年,Last.fm的Johan Oskarsson发起了一次关于分布式开源数据库的讨论,来自Rackspace的Eric Evans再次提出了NoSQL的概念,这时的NoSQL主要指非关系型、分布式、不提供ACID的数据库设计模式。
2009年在亚特兰大举行的"no:sql(east)"讨论会是一个里程碑,其口号是"select fun, profit from real_world where relational=false;"。因此,对NoSQL最普遍的解释是“非关联型的”,强调Key-Value Stores和文档数据库的优点,而不是单纯的反对RDBMS。
基于2014年的收入,NoSQL市场领先企业是MarkLogic,MongoDB和Datastax。基于2015年的人气排名,最受欢迎的NoSQL数据库是MongoDB,Apache Cassandra和Redis.
NoSQL中的四大家族主要是:列存储、键值、图像存储、文档存储,其类型产品主要有以下这些。
存储类型 |
NoSQL |
|
键值存储 |
最终一致性键值存储 |
Cassandra、Dynamo、Riak、Hibari、Virtuoso、Voldemort |
内存键值存储 |
Memcached、Redis、Oracle Coherence、NCache、 Hazelcast、Tuple space、Velocity |
|
持久化键值存储 |
BigTable、LevelDB、Tokyo Cabinet、Tarantool、TreapDB、Tuple space |
|
文档存储 |
MongoDB、CouchDB、SimpleDB、 Terrastore 、 BaseX 、Clusterpoint 、 Riak、No2DB |
|
图存储 |
FlockDB、DEX、Neo4J、AllegroGraph、InfiniteGraph、OrientDB、Pregel |
|
列存储 |
Hbase、Cassandra、Hypertable |
高可扩展性、分布式计算、没有复杂的关系、低成本
架构灵活、半结构化数据
NoSQL |
RDBMS |
代表着不仅仅是SQL 没有声明性查询语言 没有预定义的模式 键 - 值对存储,列存储,文档存储,图形数据库 最终一致性,而非ACID属性 非结构化和不可预知的数据 CAP定理 高性能,高可用性和可伸缩性 |
高度组织化结构化数据 结构化查询语言(SQL) (SQL) 数据和关系都存储在单独的表中。 数据操纵语言,数据定义语言 严格的一致性 基础事务 |
MongoDB的3大技术特色如下所示:
除了上图所示的还支持:
二级索引、动态查询、全文搜索 、聚合框架、MapReduce、GridFS、地理位置索引、内存引擎 、地理分布等一系列的强大功能。
但是其也有些许的缺点,例如:
多表关联: 仅仅支持Left Outer Join
SQL 语句支持: 查询为主,部分支持
多表原子事务: 不支持
多文档原子事务:不支持
16MB 文档大小限制,不支持中文排序 ,服务端 Javascript 性能欠佳
存储方式对比
在传统的关系型数据库中,存储方式是以表的形式存放,而在MongoDB中,以文档的形式存在。
数据库中的对应关系,及存储形式的说明
MongoDB与SQL的结构对比详解
SQL Terms/Concepts |
MongoDB Terms/Concepts |
database |
database |
table |
collection |
row |
document or BSON document |
column |
field |
index |
index |
table joins |
embedded documents and linking |
primary key Specify any unique column or column combination as primary key. |
primary key In MongoDB, the primary key is automatically set to the _id field. |
aggregation (e.g. group by) |
aggregation pipeline See the SQL to Aggregation Mapping Chart. |
JSON格式
JSON 数据格式与语言无关,脱胎于 JavaScript,但目前很多编程语言都支持 JSON 格式数据的生成和解析。JSON 的官方 MIME 类型是 application/json,文件扩展名是 .json。
MongoDB 使用JSON(JavaScript ObjectNotation)文档存储记录。
JSON数据库语句可以容易被解析。
Web 应用大量使用,NAME-VALUE 配对
BSON格式
BSON是由10gen开发的一个数据格式,目前主要用于MongoDB中,是MongoDB的数据存储格式。BSON基于JSON格式,选择JSON进行改造的原因主要是JSON的通用性及JSON的schemaless的特性。
二进制的JSON,JSON文档的二进制编码存储格式
BSON有JSON没有的Date和BinData
MongoDB中document以BSON形式存放
例如:
> db.meeting.insert({meeting:“M1 June",Date:"2018-01-06"});
这些优势造就了mongodb的丰富的功能:
JSON 文档模型、动态的数据模式、二级索引强大、查询功能、自动分片、水平扩展、自动复制、高可用、文本搜索、企业级安全、聚合框架MapReduce、大文件存储GridFS
自动复制和故障切换
多数据中心支持滚动维护无需关机支持最多50个成员
这种方式是目前构架上的主流形式,指的是通过增加服务器数量来对系统扩容。在这样的构架下,单台服务器的配置并不会很高,可能是配置比较低、很廉价的 PC,每台机器承载着系统的一个子集,所有机器服务器组成的集群会比单体服务器提供更强大、高效的系统容载量。
这样的问题是系统构架会比单体服务器复杂,搭建、维护都要求更高的技术背景。分片集群架构如下图所示:
MySQL InnoDB |
MySQL NDB |
Oracle |
MongoDB MAPI |
MongoDB WiredTiger |
|
事务 |
YES |
YES |
ES |
NO |
NO |
锁粒度 |
ROW-level |
ROW-level |
ROW-level |
Collection-level |
Document-level |
Geospatial |
YES |
YES |
YES |
YES |
YES |
MVCC |
YES |
NO |
YES |
NO |
NO |
Replication |
YES |
YES |
YES |
YES |
YES |
外键 |
YES |
YES(From 7.3) |
YES |
NO |
NO |
数据库集群 |
NO |
YES |
YES |
YES |
YES |
B-TREE索引 |
YES |
YES |
YES |
YES |
YES |
全文检索 |
YES |
NO |
YES |
YES |
YES |
数据压缩 |
YES |
NO |
YES |
NO |
YES |
存储限制 |
64TB |
384EB |
NO |
NO |
NO |
表分区 |
YES |
YES |
YES |
YES (分片) |
YES (分片) |
由下图可以看出MongoDB数据库的性能扩展能力及功能都较好,都能够在数据库中,站立一足之地。
慎用场景 |
原因 |
PB 数据持久存储大数据分析数据湖 |
Hadoop、Spark提供更多分析运算功能和工具,并行计算能力更强 MongoDB + Hadoop/Spark |
搜索场景:文档有几十个字段,需要按照任意字段搜索并排序限制等 |
不建索引查询太慢,索引太多影响写入及更新操作 |
ERP、CRM或者类似复杂应用,几十上百个对象互相关联 |
关联支持较弱,事务较弱 |
需要参与远程事务,或者需要跨表,跨文档原子性更新的 |
MongoDB 事务支持仅限于本机的单文档事务 |
100% 写可用:任何时间写入不能停 |
MongoDB换主节点时候会有短暂的不可写设计所限 |
应用特征 |
Yes/No? |
我的数据量是有亿万级或者需要不断扩容 |
|
需要2000-3000以上的读写每秒 |
|
新应用,需求会变,数据模型无法确定 |
|
我需要整合多个外部数据源 |
|
我的系统需要99.999%高可用 |
|
我的系统需要大量的地理位置查询 |
|
我的系统需要提供最小的latency |
|
我要管理的主要数据对象<10 |
在上面的表格中进行选择,但有1个yes的时候:可以考虑MongoDB;当有2个以上yes的时候:不会后悔的选择!
MongoDB官网:https://www.mongodb.com/
CentOS7.X版本软件下载地址:https://www.mongodb.org/dl/linux/x86_64-rhel70
其他版本请到进行官网下载。
在安装之前首先确认该版本软件是否支持你的操作系统。
更多详情查看:https://docs.mongodb.com/manual/installation/
Platform |
3.6 Community & Enterprise |
3.4 Community & Enterprise |
3.2 Community & Enterprise |
3.0 Community & Enterprise |
RHEL/CentOS 6.2 and later |
✓ |
✓ |
✓ |
✓ |
RHEL/CentOS 7.0 and later |
✓ |
✓ |
✓ |
✓ |
系统环境说明:
root@wiki:/root# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
root@wiki:/root# uname -a
Linux wiki 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
root@wiki:/root# /etc/init.d/iptables
-bash: /etc/init.d/iptables: No such file or directory
root@wiki:/root# geten
getenforce getent
root@wiki:/root# getenforce Disable
Disabled
root@wiki:/root# more /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
软件版本说明
本次使用的mongodb版本为:mongodb-linux-x86_64-3.6.2.tgz
root@wiki:/root# cd /home/mongodb mongodb/ mongodb-linux-x86_64-3.6.2.tgz
在root用户下操作
cat >> /etc/rc.local <<'EOF'
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
EOF
该方法仅限与CentOS系统使用,其他系统关闭参照官方文档: https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
Transparent Huge Pages (THP),通过使用更大的内存页面,可以减少具有大量内存的机器上的缓冲区(TLB)查找的开销。
但是,数据库工作负载通常对THP表现不佳,因为它们往往具有稀疏而不是连续的内存访问模式。您应该在Linux机器上禁用THP,以确保MongoDB的最佳性能。
该方法仅限与CentOS系统使用,其他系统关闭参照官方文档: https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
Transparent Huge Pages (THP),通过使用更大的内存页面,可以减少具有大量内存的机器上的缓冲区(TLB)查找的开销。
但是,数据库工作负载通常对THP表现不佳,因为它们往往具有稀疏而不是连续的内存访问模式。您应该在Linux机器上禁用THP,以确保MongoDB的最佳性能。
创建用户
groupadd -g 8000 mongod
useradd -u 8001 -g mongod mongod
修改用户密码
echo 123456 |passwd --stdin mongod
创建程序目录
root@wiki:/opt/mongodb# mkdir -p /opt/mongodb/{data,logs}
下载程序
cd /home
root@wiki:/root# wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.6.2.tgz
解压程序
tar -xvf mongodb-linux-x86_64-rhel62-3.6.2.tgz
修改程序属主
chown -R mongod:mongod /opt/mongodb
切换到mongod用户,设置用户环境变量
export MONGODB_HOME=/opt/mongodb/mongodb-linux-x86_64-3.6.2
export PATH=$MONGODB_HOME/bin:$PATH
登录MONGODB
root@wiki:/root# mongo
MongoDB shell version v3.6.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.2
Server has startup warnings:
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten]
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten]
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** WARNING: This server is bound to localhost.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** Remote systems will be unable to connect to this server.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** Start the server with --bind_ip
至此,MongoDB数据库部署完成
数据库的启动与关闭
启动:
mongod --config /opt/mongodb/mongodb.conf
root@wiki:/root# mongod --config /opt/mongodb/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 21663
child process started successfully, parent exiting
root@wiki:/root#
关闭:
mongod --shutdown --config /opt/mongodb/mongodb.conf
root@wiki:/root# mongod --shutdown --config /opt/mongodb/mongodb.conf
killing process with pid: 5677
root@wiki:/root# ps -ef|grep mongodb
参数说明:
参数 |
参数说明 |
--dbpath |
数据存放路径 |
--logpath |
日志文件路径 |
--logappend |
日志输出方式 |
--port |
启用端口号 |
--fork |
在后台运行 |
--auth |
是否需要验证权限登录(用户名和密码) |
--bind_ip |
限制访问的ip |
--shutdown |
关闭数据库 |
登入数据库
root@wiki:/root# mongo
MongoDB shell version v3.6.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.2
Server has startup warnings:
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten]
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten]
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** WARNING: This server is bound to localhost.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** Remote systems will be unable to connect to this server.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** Start the server with --bind_ip to specify which IP
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** addresses it should serve responses from, or with --bind_ip_all to
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** bind to all interfaces. If this behavior is desired, start the
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** server with --bind_ip 127.0.0.1 to disable this warning.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten]
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten]
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten]
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-04-17T10:55:56.506+0800 I CONTROL [initandlisten]
>
使用配置文件的方式管理数据库:
普通格式配置文件:
root@wiki:/root# cd /opt/mongodb/
root@wiki:/opt/mongodb# ls
data logs mongodb.conf mongodb-linux-x86_64-3.6.2 mongod.pid
root@wiki:/opt/mongodb# more mongodb.conf
# Start MongoDB as a daemon on port 27017
port = 27017
fork = true # daemonize it !
journal = true #
#rest = true
logappend = true
#auth = true
dbpath = /opt/mongodb/data/
logpath = /opt/mongodb/logs/mongod.log
pidfilepath = /opt/mongodb/mongod.pid
root@wiki:/opt/mongodb#
YAML格式配置文件(3.X 版本官方推荐使用)
cat mongod.conf
systemLog:
destination: file
path: "/application/mongodb/log/mongod.log"
logAppend: true
storage:
journal:
enabled: true
dbPath: "/application/mongodb/data"
processManagement:
fork: true
net:
port: 27017
在数据库中关闭数据库的方法
root@wiki:/opt/mongodb# mongo
MongoDB shell version v3.6.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.2
Server has startup warnings:
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten]
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten]
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** WARNING: This server is bound to localhost.
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** Remote systems will be unable to connect to this server.
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** Start the server with --bind_ip to specify which IP
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** addresses it should serve responses from, or with --bind_ip_all to
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** bind to all interfaces. If this behavior is desired, start the
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** server with --bind_ip 127.0.0.1 to disable this warning.
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten]
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten]
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten]
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-04-19T11:38:03.603+0800 I CONTROL [initandlisten]
> db
test
> use admin
switched to db admin
> db.shutdownServer()
server should be down...
2018-04-19T11:43:03.509+0800 I NETWORK [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
2018-04-19T11:43:03.510+0800 W NETWORK [thread1] Failed to connect to 127.0.0.1:27017, in(checking socket for error after poll), reason: Connection refused
2018-04-19T11:43:03.510+0800 I NETWORK [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) failed failed
> exit
bye
root@wiki:/opt/mongodb# ps -ef|grep mongodb
注:
mongod进程收到SIGINT信号或者SIGTERM信号,会做一些处理
> 关闭所有打开的连接
> 将内存数据强制刷新到磁盘
> 当前的操作执行完毕
> 安全停止
切忌kill -9
数据库直接关闭,数据丢失,数据文件损失,修复数据库(成本高,有风险)
使用kill命令关闭进程
$ kill -2 PID
原理:-2表示向mongod进程发送SIGINT信号。
或
$ kill -4 PID
原理:-4表示向mognod进程发送SIGTERM信号。
使用脚本管理mongodb服务
注:该脚本可以直接在root用户下运行
cat /etc/init.d/mongod
#!/bin/bash
#
# chkconfig: 2345 80 90
# description:mongodb
# by clsn
# blog_url http://blog.nmtui.com
#################################
MONGODIR=/application/mongodb
MONGOD=$MONGODIR/bin/mongod
MONGOCONF=$MONGODIR/conf/mongod.conf
InfoFile=/tmp/start.mongo
. /etc/init.d/functions
status(){
PID=`awk 'NR==2{print $NF}' $InfoFile`
Run_Num=`ps -p $PID|wc -l`
if [ $Run_Num -eq 2 ]; then
echo "MongoDB is running"
else
echo "MongoDB is shutdown"
return 3
fi
}
start() {
status &>/dev/null
if [ $? -ne 3 ];then
action "启动MongoDB,服务运行中..." /bin/false
exit 2
fi
sudo su - mongod -c "$MONGOD -f $MONGOCONF" >$InfoFile 2>/dev/null
if [ $? -eq 0 ];then
action "启动MongoDB" /bin/true
else
action "启动MongoDB" /bin/false
fi
}
stop() {
sudo su - mongod -c "$MONGOD -f $MONGOCONF --shutdown" &>/dev/null
if [ $? -eq 0 ];then
action "停止MongoDB" /bin/true
else
action "停止MongoDB" /bin/false
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 2
start
;;
status)
status
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
exit 1
esac
脚本管理mongodb服务
Mongodb中关键字种类:
db(数据库实例级别)
db本身
db.connection 数据库下的集合信息
db.collection.xxx(
rs(复制集级别)
sh(分片级别)
在客户端指定数据库进行连接:(默认连接本机test数据库)
root@wiki:/opt/mongodb# mongo 127.0.0.1:27017/admin
MongoDB shell version v3.6.2
connecting to: mongodb://127.0.0.1:27017/admin
MongoDB server version: 3.6.2
Server has startup warnings:
2018-04-19T13:23:42.270+0800 I CONTROL [initandlisten]
2018-04-19T13:23:42.270+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-04-19T13:23:42.270+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2018-04-19T13:23:42.270+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2018-04-19T13:23:42.270+0800 I CONTROL [initandlisten]
2018-04-19T13:23:42.270+0800 I CONTROL [initandlisten] ** WARNING: This server is bound to localhost.
2018-04-19T13:23:42.270+0800 I CONTROL [initandlisten] ** Remote systems will be unable to connect to this server.
2018-04-19T13:23:42.270+0800 I CONTROL [initandlisten] ** Start the server with --bind_ip
查看当前数据库版本
> db.version()
3.6.2
>
切换数据库
> use admin
switched to db admin
>
显示当前数据库
> db.getName()
admin
> db
admin
>
查询所有数据库
> show dbs;
admin 0.000GB
config 0.000GB
fang 0.311GB
local 0.000GB
>
查看admin数据库当前状态
> db.stats()
{
"db" : "admin",
"collections" : 1,
"views" : 0,
"objects" : 1,
"avgObjSize" : 59,
"dataSize" : 59,
"storageSize" : 16384,
"numExtents" : 0,
"indexes" : 1,
"indexSize" : 16384,
"fsUsedSize" : 5017579520,
"fsTotalSize" : 210136834048,
"ok" : 1
}
>
查看当前数据库的连接机器地址
> db.getMongo()
connection to 127.0.0.1:27017
>
创建数据库
> use test2018;
switched to db test2018
说明:
创建数据库:
当use的时候,系统就会自动创建一个数据库。
如果use之后没有创建任何集合。系统就会删除这个数据库。
删除数据库
> show dbs;
admin 0.000GB
config 0.000GB
fang 0.311GB
local 0.000GB
> use test2018
switched to db test2018
> db.dropDatabase();
{ "ok" : 1 }
>
说明:
删除数据库:
如果没有选择任何数据库,会删除默认的test数据库
创建集合
方法一:
> use 2018test
switched to db 2018test
> db.createCollection('a')
{ "ok" : 1 }
> db.createCollection('b')
{ "ok" : 1 }
>
查看当前数据下的所有集合
> show collections;
a
b
> db.getCollectionNames()
[ "a", "b" ]
>
方法二:
当插入一个文档的时候,一个集合就会自动创建。
> use fadk;
switched to db fadk
> db.c.insert({name:'clsn'});
WriteResult({ "nInserted" : 1 })
> db.c.insert({url:'http://sina.com'});
WriteResult({ "nInserted" : 1 })
查看创建的合集
> db.getCollectionNames()
[ "c" ]
>
查看合集里的内容
> db.c.find()
{ "_id" : ObjectId("5ad82aca77d34be3a911a1cb"), "name" : "clsn" }
{ "_id" : ObjectId("5ad82adf77d34be3a911a1cc"), "url" : "http://sina.com" }
>
重命名集合
> db.c.renameCollection("testccc")
{ "ok" : 1 }
> db.getCollectionNames()
[ "testccc" ]
>
删除合集
> db.createCollection('bdddd')
{ "ok" : 1 }
> db.getCollectionNames()
[ "b", "bdddd", "testccc" ]
> db.b.drop()
true
> db.getCollectionNames()
[ "bdddd", "testccc" ]
>
插入1w行数据
> for(i=0;i<10000;i++){ db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new Date()}); }
WriteResult({ "nInserted" : 1 })
查询集合中的查询所有记录
> db.log.find()
{ "_id" : ObjectId("5ad82c2577d34be3a911a1de"), "uid" : 17, "name" : "mongodb", "age" : 6, "date" : ISODate("2018-04-19T05:41:57.671Z") }
{ "_id" : ObjectId("5ad82c2577d34be3a911a1df"), "uid" : 18, "name" : "mongodb", "age" : 6, "date" : ISODate("2018-04-19T05:41:57.672Z") }
{ "_id" : ObjectId("5ad82c2577d34be3a911a1e0"), "uid" : 19, "name" : "mongodb", "age" : 6, "date" : ISODate("2018-04-19T05:41:57.673Z") }
Type "it" for more
>
注:默认每页显示20条记录,当显示不下的的情况下,可以用it迭代命令查询下一页数据。
DBQuery.shellBatchSize=50; # 每页显示50条记录
50
db.log.findOne() # 查看第1条记录
db.log.count() # 查询总的记录数
db.log.find({uid:1000}); # 查询UUID为1000的数据
删除集合中的记录数
> db.log.distinct("name") # 查询去掉当前集合中某列的重复数据
[ "mongodb" ]
> db.log.remove({}) # 删除集合中所有记录
WriteResult({ "nRemoved" : 10000 })
> db.log.distinct("name")
[ ]
查看集合存储信息
> db.log.stats() # 查看数据状态
> db.log.dataSize() # 集合中数据的原始大小
> db.log.totalIndexSize() # 集合中索引数据的原始大小
> db.log.totalSize() # 集合中索引+数据压缩存储之后的大小
> db.log.storageSize() # 集合中数据压缩存储的大小
pretty()使用
MongoDB数据库默认是没有用户名及密码的,即无权限访问限制。为了方便数据库的管理和安全,需创建数据库用户。
Ø MongoDB是没有默认管理员账号,所以要先添加管理员账号,再开启权限认证。
Ø 切换到admin数据库,添加的账号才是管理员账号。
Ø 用户只能在用户所在数据库登录,包括管理员账号。
Ø 管理员可以管理所有数据库,但是不能直接管理其他数据库,要先在admin数据库认证后才可以。
Built-In Roles(内置角色):
1. 数据库用户角色:read、readWrite;
2. 数据库管理角色:dbAdmin、dbOwner、userAdmin;
3. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
4. 备份恢复角色:backup、restore;
5. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
6. 超级用户角色:root
// 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
7. 内部角色:__system
MongoDB内建角色包括以下几类
1) 数据库用户角色
read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
2) 数据库管理员角色
dbAdmin:允许用户进行索引创建、删除,查看统计或访问system.profile,但没有角色和用户管理的权限
userAdmin:提供了在当前数据库中创建和修改角色和用户的能力
dbOwner:提供对数据库执行任何管理操作的能力。这个角色组合了readWrite、dbAdmin和userAdmin角色授予的特权。
3) 集群管理角色
clusterAdmin :提供最强大的集群管理访问。组合clusterManager、clusterMonitor和hostManager角色的能力。还提供了dropDatabase操作
clusterManager :在集群上提供管理和监视操作。可以访问配置和本地数据库,这些数据库分别用于分片和复制
clusterMonitor :提供对监控工具的只读访问,例如MongoDB云管理器和Ops管理器监控代理。
hostManager :提供监视和管理服务器的能力。
4) 备份恢复角色
backup :提供备份数据所需的能力,使用MongoDB云管理器备份代理、Ops管理器备份代理或使用mongodump
restore :提供使用mongorestore恢复数据所需的能力
5) 所有数据库角色
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
6) 超级用户角色
root:提供对readWriteAnyDatabase、dbAdminAnyDatabase、userAdminAnyDatabase、clusterAdmin、restore和backup的所有资源的访问
7) 内部角色
__system : 提供对数据库中任何对象的任何操作的特权
更多关于用户权限的说明参照:https://docs.mongodb.com/manual/core/security-built-in-roles/用户创建语法
{user: "
语法说明:
user字段:用户的名字;
pwd字段:用户的密码;
cusomData字段:为任意内容,例如可以为用户全名介绍;
roles字段:指定用户的角色,可以用一个空数组给新用户设定空角色;
roles 字段:可以指定内置角色和用户定义的角色。
进入管理数据库
> use admin
创建管理用户,root权限
db.createUser( { user: "root", pwd: "root", roles: [ { role: "root", db: "admin" } ] })
注意:
创建管理员角色用户的时候,必须到admin下创建。
删除的时候也要到相应的库下操作。
查看创建完用户后的collections;
> show tables; system.users # 用户存放位置system.version
查看创建的管理员用户
> show users { "_id" : "admin.root", "user" : "root", "db" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ] }
验证用户是否能用
> db.auth("root","root")1 # 返回 1 即为成功
用户创建完成后在配置文件中开启用户验证
cat >>/application/mongodb/conf/mongod.conf<<-'EOF'security: authorization: enabledEOF
重启服务
/etc/init.d/mongod restart
登陆测试,注意登陆时选择admin数据库
注意:用户在哪个数据库下创建的,最后加上什么库。
方法一:命令行中进行登陆
[mongod@MongoDB ~]$ mongo -uroot -proot admin MongoDB shell version: 3.2.8connecting to: admin>
方法二:在数据库中进行登陆验证:
[mongod@MongoDB ~]$ mongo MongoDB shell version: 3.2.8connecting to: test> use adminswitched to db admin> db.auth("root","root")1> show tables;system.userssystem.version
创建对某库的只读用户
在test库创建只读用户test
use testdb.createUser( { user: "test", pwd: "test", roles: [ { role: "read", db: "test" } ] })
测试用户是否创建成功
db.auth("test","test")show users;
登录test用户,并测试是否只读
show collections;db.createCollection('b')
创建某库的读写用户
创建test1用户,权限为读写
db.createUser( { user: "test1", pwd: "test1", roles: [ { role: "readWrite", db: "test" } ] })
查看并测试用户
show users;db.auth("test1","test1")
创建对多库不同权限的用户
创建对app为读写权限,对test库为只读权限的用户
use appdb.createUser( { user: "app", pwd: "app",roles: [ { role: "readWrite", db: "app" }, { role: "read", db: "test" } ] })
查看并测试用户
show usersdb.auth("app","app")
删除用户
删除app用户:先登录到admin数据库
mongo -uroot –proot 127.0.0.1/admin
进入app库删除app用户
use appdb.dropUser("app")
创建app数据库的管理员:先登录到admin数据库
use appdb.createUser({user: "admin",pwd: "admin",roles: [ { role: "dbAdmin", db: "app" } ]})
创建app数据库读写权限的用户并具有clusterAdmin权限:
use appdb.createUser({user: "app04",pwd: "app04",roles: [ { role: "readWrite", db: "app" },{ role: "clusterAdmin", db: "admin" }]})
use admin
db.createUser({user:'superadmin',pwd:'123456',roles:[{role:'root', db:'admin'}]}) ---创建超级管理员用户
db.createUser({user:'useradmin',pwd:'123456',roles:[{role:'userAdminAnyDatabase', db:'admin'}]}) ---创建用户管理员账户(能查询其他库集合,但不能查询集合内容)
db.createUser({user:'admin',pwd:'123456',roles:[{role:'readWriteAnyDatabase', db:'admin'}]}) ---创建访问任意库读写的账户
db.createUser({user:'user1',pwd:'user1',roles:[{role:'readWrite',db:'test'}]}) ---创建只对test库有读写权限的用户
db.createUser({user:"bkuser2",pwd:"Bkuser2",roles:[{role:"backup",db:"admin"}]}) ---创建用于备份时的用户,如若是恢复权限,则将backup换为restore即可
注:新建backup账户时,roles里面的db必须是admin,要不然会报错。
用户在哪个库新建授权,则需要在哪个库进行auth验证,注意一点,帐号是跟着库走的,所以在指定库里授权,必须也在指定库里验证(auth)。
>db ---查看当前所在库
test
>db.createUser({user:'test1',pwd:'test1',roles:[{role:'readWrite',db:'test'},{role:'read',db:'Johnny'})})
>use Johnny
Johnny
>db.auth('test1','test1')
Error:Authentication failed.
0 ---表示auth验证失败
>use test
>db.auth('test1','test1')
1 ---表示验证成功
所以说明一点,用户在哪个库创建,就要在哪个库auth认证,并在mongo登录时也要先连接认证库
查询用户:
查询实例中所有的用户信息
>use admin
>db.system.users.find().pretty() ---将所有用户信息查询出来
显示某一库下的所有用户
>use test
>show users ---显示在此库授权的用户信
查询指定用户的相关信息
db.getUser("jianlong") ---需要在用户所在库才能执行此命令并获得信息,查询到的信息和“show user”一样,只是可以指定用户罢了
语法结构:
db.updateUser(
"
{
customData : {
roles : [
{ role: "
...
],
pwd: "
},
writeConcern: {
可以通过此命令修改用户的权限,但使用此命令修改权限时,则会覆盖原先的所有权限
例:
db.updateUser("root",{roles:[{role:"readWriteAnyDatabase",db:"admin"}]})
在原来权限上新增权限:
> use Johnny
>db.grantRolesToUser("jianlong",[{role:'readWrite',db:'test'}]) ---不会覆盖原权限信息,只新增权限
> show users;
>use tt
>db.grantRolesToUser("jianlong",[{role:'read',db:'tt'}])
---不能在用户非授权库进行用户的权限添加,否则会报错,即表现出账户跟着库走的特点
使用db.changeUserPassword(“username","newPasswd")
> use tt
switched to db tt
>db.changeUserPassword("tuser","123456") ---注意要在账户所在授权库执行此命令
>db.dropUser("test1")
db.createRole(
{
role: "
privileges: [
{resource: {
...
],
roles: [
{role: "
...
] } )
查看角色的具体privilege(权限):
>db.getRole("SenderHis_Read",{showPrivileges:true})
另一参数:show BuiltinRoles
注:Resource具有 database 或collection 或 cluster 或 anyResource4种类型
Resource具有 database 或collection 或 cluster 或 anyResource4种类型
SQL语言与CRUD语言对照
SQL Schema Statements |
MongoDB Schema Statements |
CREATE TABLE users ( id MEDIUMINT NOT NULL AUTO_INCREMENT, user_id Varchar(30), age Number, status char(1), PRIMARY KEY (id) ) |
Implicitly created on first insert() operation. The primary key _idis automatically added if _id field is not specified. db.users.insert( { user_id: "abc123", age: 55, status: "A" } ) However, you can also explicitly create a collection: db.createCollection("users") |
ALTER TABLE users ADD join_date DATETIME |
在Collection 级没有数据结构概念。然而在 document级,可以通过$set在 update操作添加列到文档中。 db.users.update( { }, { $set: { join_date: new Date() } }, { multi: true } ) |
ALTER TABLE users DROP COLUMN join_date |
在Collection 级没有数据结构概念。然而在 document级,可以通过$unset 在update操作从文档中删除列。 db.users.update( { }, { $unset: { join_date: "" } }, { multi: true } ) |
CREATE INDEX idx_user_id_asc ON users(user_id) |
db.users.createIndex( { user_id: 1 } ) |
CREATE INDEX idx_user_id_asc_age_desc ON users(user_id, age DESC) |
db.users.createIndex( { user_id: 1, age: -1 } ) |
DROP TABLE users |
db.users.drop() |
插入/删除/更新 语句对比
SQL Statements |
MongoDB Statements |
INSERT INTO users(user_id, age status) VALUES ("bcd001", 45, "A") |
db.users.insert( { user_id: "bcd001", age: 45, status: "A" } ) |
DELETE FROM users WHERE status = "D" |
db.users.remove( { status: "D" } ) |
DELETE FROM users |
db.users.remove({}) |
UPDATE users SET status = "C" WHERE age > 25 |
db.users.update( { age: { $gt: 25 } }, { $set: { status: "C" } }, { multi: true } ) |
UPDATE users SET age = age + 3 WHERE status = "A" |
db.users.update( { status: "A" } , { $inc: { age: 3 } }, { multi: true } ) |
查询类操作对比
SQL SELECT Statements |
MongoDB find() Statements |
SELECT * FROM users |
db.users.find() |
SELECT id, user_id, status FROM users |
db.users.find( { }, { user_id: 1, status: 1, _id: 0 } ) |
SELECT user_id, status FROM users |
db.users.find( { }, { user_id: 1, status: 1 } ) |
SELECT * FROM users WHERE status = "A" |
db.users.find( { status: "A" } ) |
SELECT user_id, status FROM users WHERE status = "A" |
db.users.find( { status: "A" }, { user_id: 1, status: 1, _id: 0 } ) |
** WARNING: soft rlimits too low. rlimits set to 19193 processes, 65535 files. Number of processes should be at least 32767.5 : 0.5 times number of files.
解决办法:
cat >> /etc/security/limits.conf <32767.5mongod soft nproc 32767.5EOF
修改后,重启服务器,即可解决该问题。
[1] https://docs.mongodb.com/manual/introduction/
[2] http://www.mongoing.com/docs/introduction.html
[3] https://zh.wikipedia.org/
[4] https://docs.mongodb.com/manual/core/security-built-in-roles/