4

MongoDB基础 - Java程序员进阶

 1 year ago
source link: https://www.cnblogs.com/zhengzhaoxiang/p/17245873.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

MongoDB基础

优质博客网站:IT-BLOG-CN

MongoDB是一个强大的分布式文件存储的NoSQL数据库,天然支持高可用、分布式和灵活设计。由C++编写,运行稳定,性能高。为WEB应用提供可扩展的高性能数据存储解决方案。主要解决关系型数据库数据量大,并发高导致查询效率低下的问题,通过使用内存代替磁盘提高查询性能。

MongoDB特点:
【1】模块自由:可以把不同结构的文档存在在同一个数据库里;
【2】面向集合的存储:适合存储JSON风格文件的形式;
【3】完整的索引支持:对任何属性都可以加索引;
【4】复制和高可用性:支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。从而提供冗余备份及自动故障转移;
【5】自动分片:支持云级别的伸缩性,自动分片功能支持水平的数据库集群,可动态添加额外的机器;
【6】丰富的查询:支持丰富的查询表达方式,查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组;
【7】快速更新查询:查询优化器会分析查询表示式,并生成一个高效的查询计划;
【8】高效的传统存储方式:支持二进制数据及大型对象(如图片);

二、基本操作

MongoDB将数据存储在一个文件,数据结构由键值key:value对组成,类似于JSON对象,字段值包含其他文档、数组、文档数组。

SQL术语 MongoDB术语 说明
DataBase DataBase 数据库
Table Collection 数据库表/集合:存储多个文档,结构不固定{'name':'zzx','gender':'男'}{'class':'一班','count':'10'}
Row Document 数据记录行/文档就是一个对象,由键值对构成,是JSON扩展的BSON格式{'name':'zzx','gender':'男'}
Column Field 数据字段/域
Index Index 索引
Table Joins 表连接,MongoDB不支持
Primary Key Primary Key 主键,MongoDB自动将_id设置为主键
// 创建
db.createCollection(name, options)
// 查看集合
show collections
// 删除
db.集合名称.drop()

name要创建的集合名称,options是一个文档,用于制定集合的配置,选项参数是可选的:参数capped:默认为false表示不设置上限;参数size:当capped值为true时,需要指定此参数,表示设置上限的大小,会覆盖之前的值,单位为字节。

db.createCollection("stu")
db.createCollection("stu", { capped: true, size: 20})
类型 说明
Object ID 文档ID,每个文档都有一个属性,为_id保证一个文档的唯一性,可以自己设置,如果没有设置自动提供一个特别的_id,类型为objectID:12字节的十六进制数,前4个字节时时间戳,接下来3个字节是机器ID,接下来2个字节服务进程ID最后三位是增量值
String 字符串UTF-8
Boolean 布尔
Integer 整形
Double 布尔
Arrays 数组或列表
Object 嵌入式的文档,MongoDB是不能维护关系的,可以通过嵌入文档的形式来维护这个关系
Null 空值
Timestamp 时间戳
Date 日期UNIX时间格式
// 插入
db.集合名称.insert(document)

//案例1
db.stu.insert({name:'zzx',gender:1}) //自动生成_id
//案例2
s1={_id:'43444433',name:'zzx'}
s1.gender=0
db.stu.insert(s1)

// 修改
db.集合名称.update(
    <query>, // 查询条件,类似sql中的where部分
    <update>,  // 类似sql中的 set部分
    {$multi:<boolean>} // 默认false值改第一条记录,true表示修改满足的所有数据
)

//案例
db.stu.update({name:'zzx'},{name:'fj'}) // 整个文档的结构都会发生变化
db.stu.update({name:'zzx'},{$set:{name:'fj'}}) // 只会修改 name的属性

// 保存:如果数据存在进行修改,不存在进行插入
db.集合名称.save(document)

// 删除
db.集合名称.remove(
    <query>,
    {
        justOne:<boolean> //默认false会删除多条
    }
)
// 查询
db.集合名称.find(条件文档)
// 查询一条数据
db.集合名称.findOne(条件文档)

//案例 and和or一起使用。运算法符:$lt小于 $lte小于等于 $gt大于 $gte大于等于 $ne不等于 使用//或者$regex编写正则表达式
db.stu.find({$or:[{age: {$gte: 18}}, {gender: 1}], name: 'zzx'})
db.stu.find({name:{$regex:'^黄'}})
db.stu.find({name:/^黄/})

// ** 自定义查询:使用 $where后面写一个函数
db.stu.find({$where:function(){return this.age > 20}})

// limit()用于读取指定数量的文档
db.集合名称.find().limit(NUMBER) //NUMBER表示文档的条数
// skip()用于跳过指定数量的文件,配合limit实现分页功能,与limit同时使用的时候不分先后顺序。
db.集合名称.find().skip(NUMBER)

//投影:查询的结构集只选择必要的字段
db.集合名称.find({},{字段名称:1,...}) // 对需要显示的字段设置为1,id默认会返回,如果不想返回可以设置为0

// 排序 sort()
db.集合名称.find().sort({字段:1,...}) // 1升序,-1降序
// 统计 count()
db.集合名称.find().count({条件}) //find可以省略
db.stu.count({age:{$gt:20},gender:1})

// 去重distinct()
db.集合名称.distinct({去重字段,{条件}})

主要用于计算数据,类似sql中的sum()avg()

常用的管道:$group将集合中的文档分组,可用于统计结果;$match过滤数据,只输出符合条件的文档;$project修改输入文档的结构,如重命名、增加、删除字段、创建计算结果;$sort将输入文档排序后输出;$limit限制聚合管道返回的文档数;$skip跳过指定数量的文档,返回剩余文档;$unwind将数组类型的字段进行拆分;

常用的表达式:$sum计算综合,$sum:1count表示计数;$avg计算平均值;$min获取最小值;$max获取最大值;$push在结果文档中插入值到下一个数组中;$first根据资源文件的排序获取第一个文档数据;$last根据资源文档的排序获取最后一个文档数据。

db.集合名称.aggregate([{管道:{表达式}}]) //管道在Linux中一般用于将当前命令的输出结果作为下一个命令的输入,在MongoDB中是同样的作用

分组$group

// 统计男女的总人数 _id表示组分的依据,使用某个字段的格式为'$字段',如果需要得到整个文档可以使用 '$$ROOT' 替换 '$age'
db.stu.aggregate([
    {$group:{
        _id:'$gender',
        counter:{$push:'$age'}
    }}
])
// 输入
{"_id":男,"counter":[12,45]}
{"_id":女,"counter":[22,15]}

过滤数据$match

db.stu.aggregate([
    {$match:{age:{$gt:20}}},
    {$group:{_id:'$gender',counter:{$sum:1}}}
])

投影$project:只显示某个字段

db.stu.aggregate([
    {$group:{_id:'$gender',counter:{$sum:1}}},
    {$project:{_id:0,counter:1}}
])

排序$sort

db.stu.aggregate([
    {$group:{_id:'$gender',counter:{$sum:1}}},
    {$sort:{counter:-1}}
])

$limit 和 $skip

db.stu.aggregate([
    {$group:{_id:'$gender',counter:{$sum:1}}},
    {$sort:{counter:-1}},
    {$skip:1},
    {$limit:1}
])

$unwind 将数组类型的字段进行拆分,如果不是数组是一个属性,就单独输出该属性

db.集合名称.aggregate([{$unwind:'$字段名称'}])

db.stu.insert({name:'zzx',size:['S','Z','L']})
db.stu.aggregate([
    $unwind:'$size'
])

// 处理是空数组,无字段,null的情况使用上述 $unwind数据会丢失,可以使用下面表达式,防止数据丢失
db.stu.aggregate([
    {$unwind:{
        path:'$字段名称',
        preserverNullAndEmptyArrays:<boolean> //防止数据丢失
    }}
])

MongoDB通过索引提升查询速度

// 使用explain()命令分析查询性能
db.stu.find({name:'zzx100000'}).explain('executionStats')
// 分析结果如下:
"executionStats": {
    "executionSuccess": true,
    "nReturned": 1,
    "executionTimeMillis": 96,
    "totalKeysExamined": 0,
    "totalDocsExamined": 100000,
}

建立索引: 1表示升序,-1表示降序

db.集合.ensureIndex({属性:1})
db.stu.ensureIndex({name:1})

// 对索引属性查询
db.stu.find({name:'zzx100000'}).explain('executionStats')
// 分析结果如下:
"executionStats": {
    "executionSuccess": true,
    "nReturned": 1,
    "executionTimeMillis": 1,
    "totalKeysExamined": 0,
    "totalDocsExamined": 100000,
}

// 唯一索引
db.stu.ensureIndex({'name':1},{'unique':true})
// 联合索引
db.stu.ensureIndex({name:1,age1})
// 查看索引
db.stu.getIndexes()
// 删除所以
db.stu.dropIndexes('索引名称')

为了更安全的访问MongoDB,需要创建用户。采用角色、用户、数据库的安全管理方式。常用的角色如下:root只在admin数据库中可用,超级账号,超级权限。Read用户只读权限,readWrite用户读写权限。

// 创建超级管理员
use admin // admin是数据库
db.createUser({
    user:'admin',
    pwd:'123',
    roles:[{role:'root',db:'admin'}]
})

启用安全认证:修改配置文件

sudo vi /etc/mongod.conf

启用身份认证:keys and values之间一定要有空格,否则解析错误。修改完配置文件后,必须重启服务。

security:
    authorization: enable

数据库连接

mongo -u admin -p 123 --authenticationDatabase admin

五、备份与恢复

复制提供数据冗余备份,并在多个服务器上存储数据副本,提高数据的可用性,并保证数据的安全性,允许从硬件故障和服务中断中恢复数据。常见的搭配是一主多从。主节点记录所有操作,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证数据的一致性。

优点:
【1】数据备份;
【2】数据灾难恢复(自动故障转移,自动恢复);
【3】读写分离;
【4】高数据可用;
【5】无宕机维护;
【6】副本集对应用程序是透明的;

设置复制节点:

mongod --bind_ip 192.168.113.122 --port 27017 --dbpath ./mongdb/file1 --replSet rs0 // rs0副本集,master和slave的副本集相同
mongod --bind_ip 192.168.154.132 --port 27017 --dbpath ./mongdb/file1 --replSet rs0

通过客户端连接MongoDB master,并在master上面进行初始化,同时添加其他副本集(也就是备份的服务器信息)。如果在从服务器上进行读操作,需要设置rs.slaveOk()

mongo --host 192.168.113.122 --port 27017 // 主服务器

rs.initiate()  //rs是mongodb提供的副本集管理对象

rs.add('192.168.154.132:27017') // 从服务器

rs.salveOk()

手动备份:

mongodump -h dbhost -d dbname -o dbdirectory
mongorestore -h dbhost -d dbname --dir dbdirectory

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK