原创:Spring Boot + MongoDB 实战指南 - 从安装mongodb到java spring boot编码运行完整笔记
本人原创未经许可可随意转载!
1.2功能特性:
1.3 MongoDB主要应用场景如下:
1)网站实时数据处理。(它非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。)
2)缓存。(由于性能很高,它适合作为信息基础设施的缓存层。在系统重启之后,由它搭建的持久化缓存层可以避免下层的数据源过载。)
3)高伸缩性的场景。(非常适合由数十或数百台服务器组成的数据库。)
4)大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
5)用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询。
1.4 不适用的场景如下:
1)要求高度事务性的系统。
2)传统的商业智能应用(需要高度优化)。
3)复杂的跨文档(表)级联查询(牵扯到SQL的问题)。
1.5 MongoDB存储引擎及原理:
wiredTiger引擎:3.0新增引擎,官方宣称在read、insert和复杂的update下具有更高的性能。所有的write请求都基于“文档级别”的lock,因此多个客户端可以同时更新一个colleciton中的不同文档,这种更细颗粒度的lock,可以支撑更高的读写负载和并发量。因为对于生产环境,更多的CPU可以有效提升wireTiger的性能,因为它的IO是多线程的。wiredTiger不像MMAPV1引擎那样尽可能的耗尽内存,它可以通过在配置文件中指定“cacheSizeGB”参数设定引擎使用的内存量,此内存用于缓存工作集数据(索引、namespace,未提交的write,query缓冲等)。
journal就是一个预写事务日志,来确保数据的持久性,wiredTiger每隔60秒(默认)或者待写入的数据达到2G时,mongodb将对journal文件提交一个checkpoint(检测点,将内存中的数据变更flush到磁盘中的数据文件中,并做一个标记点,表示此前的数据已经持久存储在了数据文件中,此后的数据变更存在于内存和journal日志)。对于write操作,首先被持久写入journal,然后在内存中保存变更数据,条件满足后提交一个新的检测点,即检测点之前的数据只是在journal中持久存储,但并没有在mongodb的数据文件中持久化,延迟持久化可以提升磁盘效率,如果在提交checkpoint之前,mongodb异常退出,此后再次启动可以根据journal日志恢复数据。journal日志默认每个100毫秒同步磁盘一次,每100M数据生成一个新的journal文件,journal默认使用了snappy压缩,检测点创建后,此前的journal日志即可清除。mongod可以禁用journal,这在一定程度上可以降低它带来的开支;对于单点mongod,关闭journal可能会在异常关闭时丢失checkpoint之间的数据(那些尚未提交到磁盘数据文件的数据);对于replica set架构,持久性的保证稍高,但仍然不能保证绝对的安全(比如replica set中所有节点几乎同时退出时)。
2.1 解压包
tar zxvf mongodb-linux-x86_64-rhel70-3.6.9.tgz
2.2 将解压后的文件移动到 /usr/local/ 下并改名mongodb
mv mongodb-linux-x86_64-rhel70-3.6.9 /usr/local/mongodb
2.3 mongodb安装完后需手动创建数据文件存储目录和日志文件目录以及配置文件:
进入mongodb根目录,创建文件夹data和logs
mkdir data,logs
再进入mongodb /bin目录下创建配置文件mongodb.conf
touch mongodb.conf
2.4 编辑mongodb.conf文件,配置内容如下:
bind_ip=0.0.0.0 #外部连接的话需设置该ip
dbpath = /usr/local/mongodb/data #数据文件存放目录
logpath = /usr/local/mongodb/logs/mongodb.log #日志文件存放目录
port = 27017 #默认端口号
fork = true #服务启动后,进程在后台运行
auth=true #开启用户验证(mongodb默认情况下是不开启安全验证的,用户无需登录就可任意操作数据库,为安全起见需开启安全验证,开启验证需创建用户)
【注:auth暂时设为false,因为此时还没有创建用户,如果设为true,将不能进行用户创建操作。创建完用户后设为true,重启服务即可。】
2.5 配置环境变量:
vim /etc/profile
追加内容:
export MONGODB_HOME=/usr/local/mongodb
export PATH=$PATH:$MONGODB_HOME/bin
2.6 在mongodb /bin目录下启动服务
./mongod –f mongodb.conf
连接服务并创建用户同时分配权限
2.7 在mongodb /bin目录下连接服务
./mongo
2.8创建用户分配权限
2.8.1切换到内置数据库admin,默认是test库
use admin
查看当前所在数据库
db
2.8.2 在admin库下创建用户分配权限
db.createUser({user:”username”, pwd:”password”, roles:[{role:”root”, db:”admin”}]})
user:用户名,pwd:密码,role:角色,持有权限,db:作用于哪个数 据库。
2.8.3内建角色权限介绍:
2.9 进行验证
用户信息是记忆在某个库下的,在哪个库下创建的用户,就必须在 哪个库下进行验证。上面是在admin库下创建的用户,所以要在admin 库下进行验证。(先将配置文件中的auth设为true,重启服务:use admin , db.shutdownServer(),此时服务已关闭,ctrl+c退出连接,./mongod –f mongodb.conf 启动服务,./mongo 连接服务)
use admin
db.auth(“username”,”password”)
如果返回1,说明验证成功。因为刚刚授予的是root最高权限,所以可以对任何库进行任何操作。
3.1 创建普通用户
作用在admin下的用户属于管理员用户,其他人连接需要给他创建普通用户,并对不同的用户授予不同的权限。例如:
use product #切换到product库
db.createUser({user:”username”,
pwd:”password”,
roles:[
{role:”readWrite”,db:”product”},
{role:”read”,db:”test”}
]})
该例子为:在product库下创建了一个用户,持有权限为,对product库有读写权限,对read库有只读权限。
【注:】mongodb的库和表不需要进行特意的创建,如:
use product #切换到不存在的库product
db.product_collection.insert({x:1}) #向product_collection集合中插入一条数据,此时product库和product_collection集合将自动创建。
show dbs #查看有哪些库
show tables/collection #查看当前库下有哪些表
创建成功后Ctrl + c 退出连接,然后./mongo重新连接,
切换到product库,验证刚刚创建的普通用户:
use product
db.auth(“username”,”password”)
【注:】上面提到过,用户是在哪个库下被创建的就必须在哪个库下验证,尽管该用户持有对test库的只读权限,但必须通过在product库下验证成功后,才能对test库进行读取操作。
3.2 用户管理(该用户必须持有能够对用户操作的权限,对某个用户的操作需切换到用户所在库)
查看所有用户
db.system.users.find().pretty()
查看当前库下有哪些用户
show users
修改用户密码
db.changeUserPassword(“username”,”newpassword”)
修改用户权限
db.updataUser(“username”,{roles:[{role:”readWrite”, db:”test”]})
注:updataUser是完全替换之前的值,如果要新增权限,则:
db.grantRolesToUser(“username”,[{role:”readWrite”,db:”test”},{role:”readWrite”,db:”news”}])
删除权限
db.revokeRolesFromUser(“username”,[{role:”readWrite”, db:”news”}])
删除用户
db.dropUser(“username”)
3.3 基础语法
Mysql MongoDB
术语:表(table) -- 集合(collection)
行(row) -- 文档(douctment)
列(coulmb) -- 字段(fild)
查看所有数据库
>show dbs
查看当前数据库
>db
切换数据库
>use [dbname]
删除当前数据库
>db.dropDatabase()
向当前数据库的某个集合中插入数据 (当前数据库不存在或集合不存在,会自动创建)
默认主键(_id)可在插入时指定
>db.collectionname.insert({key:val,key:val})
查看当前数据库的所有集合
>show collections/tables
查询某个集合中所有文档
>db.collectionname.find()
查询集合中第一条文档
>db.collectionname.findOne()
条件查询 (查询x为1的文档)
>db.collectionname.find({x:1})
查看集合中有多少条数据
>db.collectionname.find().count()
分页查询 跳过前3条数据(起始行) 限制只返回两条 并根据x排序
>db.collectionname.find().skip(3).limit(2).sort({x:1})
更新x:1的文档为x:999
>db.collectionname.updata({x:1},{x:999})
更新部分字段 {x:100,y:100,z:100}
更新z:100文档中的y:99,x:888
>db.collectionname.update({z:100,[k:v]...},{$set:{y:99,x:888,[k:v]...}})
更新不存在的数据 (y:1000是不存在的文档) 加true
>db.collectionname.update({y:1000},{y:10001},true)
多文档更新,条件满足x:1的所有文档更新为x:2(普通更新只能更新第一条满足条件的文档)
>db.collectionname.update({x:1},{$set:{x:2}},false,true)
删除文档(必须传入条件,会删除所有满足条件的文档)
>db.collectionname.remove({x:1})
删除集合
>db.collectionname.drop()
3.3 索引
查看当前集合索引
>db.collectionname.getIndexes()
创建索引(x代表字段名字,val而是代表方向,1代表正向排序,-1代表逆向排序)
>db.collectionname.ensureIndex({x:1})
索引种类:
1. _id索引(绝大多数集合默认建立的索引)
2. 单建索引(最普通的索引,需要自己创建)
3. 多建索引(创建形式相同,区别在于字段的值
单建索引:值为一个单一的值。例如字符串,数字或日期
多建索引:值具有多个记录,例如数组)
4. 复合索引(当查询条件不止一个时,需要建立复合索引)
>db.collectionname.ensureIndex({x:1,y:2})
5. 过期索引(指定时间后索引会过期,并删除相应数据。可用于存放用户登录信息的数据或日志)
expireAfterSeconds:10, 设置过期时间,s/单位
>db.collectionname.ensureIndex({time:newDate()},{expireAfterSeconds:10})
注:存储在过期索引字段的值必须是指定的时间类型
必须是ISODate或者ISODate数据,不能使用时间戳,否则不能被自动删除。
过期索引不能是复合索引
删除时间不是精确的(删除的过程是由后台程序每60秒跑一次,而且删除也需要一些时间,所以存在误差且最快是在60秒后才会删除)
6. 全文索引
建立方法:(key代表字段名,val是固定的字符串text,每个集合只能创建一个全文索引)
db.collectionname.ensureIndex({key:"text"})
db.collectionname.ensureIndex({key_1:"text",key_2:"text"})
db.collectionname.ensureIndex({"$**":"text"})
使用方法:(不需要通过k:v来设置条件,通过{$text:{$search:"内容1 内容2 \"内容3\""}} 来匹配值中存在该内容的所有文档结果)
db.collectionname.find({$text:{$search:"aa"}})
db.collectionname.find({$text:{$search:"aa bb"}}) [aa或bb]
db.collectionname.find({$text:{$search:"aa bb -cc"}}) [aa或bb 但不能包含cc]
db.collectionname.find({$text:{$search:"\"aa\" \"bb\""}}) [既包含aa又包含bb]
全文索引相似度:
$meta操作符:{score:{$meta:"textScore"}}
写在查询条件后面可以返回返回结果的相似度,与sort一起使用可以达到更好的实用效果
例:db.collectionname.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}})
返回的结果中包含score字段,值为相似度,可对score进行排序 db.collectionname.find({$text:{$search:"aabb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
全文索引限制:
每次查询,只能指定一个$text查询
$text查询不能出现在$nor(排除查询条件)查询中
查询中如果包含了$text,hint(手工指定索引)不再起作用
范例git地址:http://134.98.1.202:8081/zhi/mgdemo.git
第一步:
将balance表从MySQL中导出,右键,点击导出向导,选择格式为csv。
第二步:
导出完成后,用记事本或notepad++打开,然后将编码格式转为UTF-8
第三步:
打开Studio 3T视图工具,右击Collections选择Import Collections,选择csv
选择文件:然后一直next
2.1 复制集是由一组拥有相同数据集的mongodb实例所组成的集群。能够提供数据冗余以及高可用。
两类节点:
主节点:接收所有来自客户端的写操作,一个复制集只能有一个主节点。主节点通过将所有数据集的变动(写操作,不包含读操作)记录到oplog中。从节点则通过主节点的oplog来进行复制操作,由于一个复制集中只有主节点能够进行写操作,从节点是绝对无法写入的,杜绝了人为干预的可能性,充分保障了数据的一致性。
写操作我们知道了,如何读取数据。默认情况下读请求也是经过主节点的,因为复制集是异步执行的,可能由于磁盘的刷盘效率以及网络延迟等等,造成从节点的数据相对于主节点来说有一定的延迟,所以驱动在没有进行配置的情况下,默认是将读请求指向主库的。如果对某些数据时效性要求不是很严格的话,也可通过驱动的复制集读选项将读请求优先指向从库,分担主库压力,实现读写分离。
2.2 复制集特点:
1)主节点是唯一的,但不固定。当主节点故障时,集群会自动将其移除并通过选举,选择一个从节点充当新的主节点。
2)大多数原则(也称二分之一原则)。集群存活节点小于等于二分之一时集群不可写,只可读。(复制集的服务器挂了一半就没法选举了,将全部降为从节点,只有当健康的节点数大于节点总数的二分之一时,才会进行新的主节点选举)。
3)从库无法写入。MySQL从库的readonly对具有super权限的账户无效。
4)自动容灾。
全部,完整源码:https://github.com/yunxunmi/mongodbdemo
相关基于SpringBoot的代码生成器预计近期推出
针对Spring Boot + Mysql + 本人数据库中间件的代码生成器下载地址:https://download.csdn.net/download/tengyunjiawu_com/10707537