一、NOSQL简介:
1、分布式系统:多台计算机和通信软件组成
2、分布式优点:
1)可靠性、容错性:一台服务器的系统崩溃不会影响到其余服务器
2)可扩展性
3)资源共享
4)灵活性:容易安装 实施和调试新的服务
5)速度快
6)性能好
3、分布式缺点:
更少的软件支持 网路基础设施问题 安全性
4、为什么使用NoSQL?
如今 用户的个人信息、社交网络、地理位置、用户的数据和用户操作日志城北增加
如果对这些用古湖数据进行挖掘 SQL数据库不适用这些应用
5、RDBMS vs NOSQL
RDBMS 严格的一致性 基础事务
NOSQL 值对存储 列存储 文档存储 图形数据库 最终一致性 高性能 高可用性 和可伸缩 性
6、CAP定理
1)一致性 所有节点在同一时间具有相同的数据
2)可用性 保证每个请求不管成功还是失败都有响应
3)分区容错性 系统中任意信息的丢失或失败不会影响系统的继续运作
7、NOSQL优缺点
1)优点:高可扩展性、分布式计算、低成本、架构的灵活性、没有复杂的关系
2)缺点:没有标准化 、有限的查询功能
8、NOSQL数据库分类
二、MongoDB简介
1、什么是MongoDB?
MongoDB是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统
在高负载情况下,添加更多的节点 可以保证服务器性能
MongoDB旨在为WEB应用提供可扩展的高性能数据存储解决方案
MongoDB将数据存储为一个文档 数据结构由键值对组成 MongoDB文档类似于JSON对象 字段值可以包含其他文档 数组及文档数组
2、主要特点
1)面向文档存储的数据库 操作起来比较简单和容易
2)可以在MongoBD记录中设置任何属性的索引来实现更快的排序
3)支持丰富的查询表达式
4)允许在服务段执行脚本
5)支持多种编程语言
3、MongoDB概念解析
1)数据库
show dbs 显示所有数据的列表
db 显示当前数据库对象
use +数据库名 连接到一个指定的数据库
2)、文档 Document
文档是一组键值对 BSON
{"site":"www.runoob.com", "name":"菜鸟教程"}
3)、集合
集合是MongoDB文档组 类似于数据库中的表格
如:
{"site":"www.baidu.com"}
{"site":"www.google.com","name":"Google"}
{"site":"www.runoob.com","name":"菜鸟教程","num":5}
4)、MongoDB数据类型
三、MongoDB常用操作
1、创建数据库 use +db_name
use mydb
查看所有数据库 show dbs
2、删除数据库
切换到指定数据库 use mydb 执行删除 db.dropDataBase()
3、创建集合
use mydb
db.createCollection("collection")
查看已有集合 show collections
在mongoDB中 不需要创建集合 当插入一些文档时 会自动创建集合
db.mycol.insert("name":"zhangsan")
4、插入文档
db.collection_name.insert(document)
如
>db.col.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: '菜鸟教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
查看已插入文档:
> db.col.find()
{ "_id" : ObjectId("56064886ade2f21f36b03134"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
>
也可以将数据定义为一个变量
> document=({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: '菜鸟教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
});
执行插入操作
> db.col.insert(document)
WriteResult({ "nInserted" : 1 })
>
3.2 版本后还有以下几种语法可用于插入文档:
db.collection.insertOne():向指定集合中插入一条文档数据
db.collection.insertMany():向指定集合中插入多条文档数据
5、更新文档
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
6、删除文档
db.col.remove({'title':'MongoDB 教程'})
7、查询文档
and条件
>db.col.find({key1:value1, key2:value2}).pretty()
8、排序
在 MongoDB 中使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
>db.COLLECTION_NAME.find().sort({KEY:1})
9、聚合
MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
有点类似 SQL 语句中的 count(*)。
{
_id: ObjectId(7df78ad8902c)
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
_id: ObjectId(7df78ad8902d)
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
_id: ObjectId(7df78ad8902e)
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
},
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{
"result" : [
{
"_id" : "runoob.com",
"num_tutorial" : 2
},
{
"_id" : "Neo4j",
"num_tutorial" : 1
}
],
"ok" : 1
}
>
类似
select by_user, count(*) from mycol group by by_user
10、
MongoDB索引
>db.collection.createIndex(keys, options)
语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。
>db.col.createIndex({"title":1})
11、
MongoDB复制
MongoDB复制是将数据同步在多个服务器的过程。
复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
复制还允许您从硬件故障和服务中断中恢复数据。
复制的作用:
保障数据的安全性 数据的高可用性 灾难恢复 无需停机维护 分布式读取数据
复制原理
主从结构 主节点记录其上所有的操作日志 从节点 定期轮询主节点获取这些操作 然后对自己的数据副本执行这些操作 从而保证从节点数据与主节点一致
12、备份与恢复
数据集备份
使用mongodump命令来备份mongoDB的数据,该命令可以到处所有数据到指定目录中
>mongodump -h dbhost -d dbname -o dbdirectory
MongoDB数据恢复
>mongorestore -h <hostname><:port> -d dbname <path>
13、
MongoDB监控
在安装mongoDB服务后,为了了解MongoDB的运行情况,并查看MongoDB的性能
这样在大流量的情况下可以很好的应对并保证MongoDB正常运行
mongostat命令
mongostat是mongodb自带的状态检测工具,在命令行下使用,会间隔固定时间获取Monogodb的当前运行状态
mongotop命令
mongotop也是mongodb下的一个内置工具,mongotop提供了一个方法,用来跟踪一个MongoDB的实例,查看哪些大量的时间花费在读取和写入数据。 mongotop提供每个集合的水平的统计数据。默认情况下,mongotop返回值的每一秒
四、MongoDB Java
1、安装mongoDB JDBC驱动 mongo-java-driver-3.2.2.jar
2、连接数据库
public class MongoDBJDBC {
public static void main(String[] args){
try {
//连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址
//ServerAddress()两个参数分别为 服务器地址 和 端口
ServerAddress serverAddress = new ServerAddress("localhost",27017);
List<ServerAddress> addrs = new ArrayList<ServerAddress>();
addrs.add(serverAddress);
//MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
credentials.add(credential);
//通过连接认证获取MongoDB连接
MongoClient mongoClient = new MongoClient(addrs,credentials);
//连接到数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("databaseName");
System.out.println("Connect to database successfully");
} catch (Exception e) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}
3、创建集合
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
public class MongoDBJDBC{
public static void main( String args[] ){
try{
// 连接到 mongodb 服务
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");
System.out.println("Connect to database successfully");
mongoDatabase.createCollection("test");
System.out.println("集合创建成功");
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}
3、获取集合
com.mongodb.client.MongoDatabase类的 getCollection() 方法
4、插入文档
使用com.mongodb.client.MongoCollection类的 insertMany() 方法来插入一个文档
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
public class MongoDBJDBC{
public static void main( String args[] ){
try{
// 连接到 mongodb 服务
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");
System.out.println("Connect to database successfully");
MongoCollection<Document> collection = mongoDatabase.getCollection("test");
System.out.println("集合 test 选择成功");
//插入文档
/**
* 1. 创建文档 org.bson.Document 参数为key-value的格式
* 2. 创建文档集合List<Document>
* 3. 将文档集合插入数据库集合中 mongoCollection.insertMany(List<Document>) 插入单个文档可以用 mongoCollection.insertOne(Document)
* */
Document document = new Document("title", "MongoDB").
append("description", "database").
append("likes", 100).
append("by", "Fly");
List<Document> documents = new ArrayList<Document>();
documents.add(document);
collection.insertMany(documents);
System.out.println("文档插入成功");
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}
5、检索集合所有文档
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
public class MongoDBJDBC{
public static void main( String args[] ){
try{
// 连接到 mongodb 服务
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");
System.out.println("Connect to database successfully");
MongoCollection<Document> collection = mongoDatabase.getCollection("test");
System.out.println("集合 test 选择成功");
//检索所有文档
/**
* 1. 获取迭代器FindIterable<Document>
* 2. 获取游标MongoCursor<Document>
* 3. 通过游标遍历检索出的文档集合
* */
FindIterable<Document> findIterable = collection.find();
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}
6、更新文档
import org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
public class MongoDBJDBC{
public static void main( String args[] ){
try{
// 连接到 mongodb 服务
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");
System.out.println("Connect to database successfully");
MongoCollection<Document> collection = mongoDatabase.getCollection("test");
System.out.println("集合 test 选择成功");
//更新文档 将文档中likes=100的文档修改为likes=200
collection.updateMany(Filters.eq("likes", 100), new Document("$set",new Document("likes",200)));
//检索查看结果
FindIterable<Document> findIterable = collection.find();
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}