什么是NoSQL?
NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。
NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
为什么使用NoSQL ?
今天我们可以通过第三方平台(如:Google,Facebook等)可以很容易的访问和抓取数据。用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加。我们如果要对这些用户数据进行挖掘,那SQL数据库已经不适合这些应用了, NoSQL数据库的发展也却能很好的处理这些大的数据。
RDBMS vs NoSQL
RDBMS
- 高度组织化结构化数据
- 结构化查询语言(SQL) (SQL)
- 数据和关系都存储在单独的表中。
- 数据操纵语言,数据定义语言
- 严格的一致性
- 基础事务
NoSQL
- 代表着不仅仅是SQL
- 没有声明性查询语言
- 没有预定义的模式
-键 - 值对存储,列存储,文档存储,图形数据库
- 最终一致性,而非ACID属性
- 非结构化和不可预知的数据
- CAP定理
- 高性能,高可用性和可伸缩性
CAP定理(CAP theorem)
在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer's theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
- 一致性(Consistency) (所有节点在同一时间具有相同的数据)
- 可用性(Availability) (保证每个请求不管成功或者失败都有响应)
- 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
- CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
- CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
- AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
什么是MongoDB ?
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
MongoDB安装
https://www.cnblogs.com/ymwangel/p/5859453.html
主要特点
- MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。
- 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")来实现更快的排序。
- 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
- 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
- Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
- MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
- Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
- Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
- Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
- GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
- MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
- MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
MongoDB常用命令
一、基本命令
1.创建数据库
use test1;
2. 查询所有数据库
show dbs;
3. 删除当前使用数据库
db.dropDatabase();
4.从指定的机器上复制指定数据库数据到某个数据库
db.copyDatabase("mydb", "temp", "127.0.0.1");
5.修复当前数据库
db.repairDatabase();
6.查看当前使用的数据库名称
db.getName();
7.显示当前db状态
db.stats();
8. 查看当前db版本
db.version();
9.查看当前db的链接机器地址
db.getMongo();
二、Collection聚集集合
1、创建一个聚集集合(table)
db.createCollection(“collName”, {size: 20, capped: 5, max: 100});
2、得到指定名称的聚集集合(table)
db.getCollection("account");
3、得到当前db的所有聚集集合
db.getCollectionNames();
三、用户相关
1、添加一个用户(添加用户、设置密码、是否只读)
db.addUser("name");
db.addUser("userName", "pwd123", true);
2、数据库认证、安全模式
db.auth("userName", "123123");
3、显示当前所有用户
show users;
4、删除用户
db.removeUser("userName");
四、聚集集合查询
1、查询所有记录
db.userInfo.find();
3、查询age = 22的记录
db.userInfo.find({"age": 22});
4、查询age > 22的记录
//大于
db.userInfo.find({age: {$gt: 22}});
//小于
db.userInfo.find({age: {$lt: 22}});
5、按照年龄排序
升序:db.userInfo.find().sort({age: 1});
降序:db.userInfo.find().sort({age: -1});
6、查询name = zhangsan, age = 22的数据
db.userInfo.find({name: 'zhangsan', age: 22});
7、查询前5条数据
db.userInfo.find().limit(5);
8、查询10条以后的数据
db.userInfo.find().skip(10);
9、查询在5-10之间的数据
db.userInfo.find().limit(10).skip(5);
10、查询某个结果集的记录条数
db.userInfo.find({age: {$gte: 25}}).count();
11、添加一条数据
db.users.save({name: ‘zhangsan', age: 25, sex: true});
12、修改一条数据
db.users.update({age: 25}, {$set: {name: 'changeName'}}, false, true);
相当于:update users set name = ‘changeName' where age = 25;
13、删除数据
db.users.remove({age: 132});
14、循环添加数据
> for (var i = 0; i < 30; i++) {
... db.users.save({name: "u_" + i, age: 22 + i, sex: i % 2});
... };
MongoDB事务
在分布式存储解决方案中谈事务一直是件很痛苦的事情,而事务也成了大部分NoSQL解决方案短板所在。引入NoSQL数据库后,文档间ACID事务的支持通常就取消了。许多键/值存储仍有ACID,但它只适用于单个条目,取消ACID的主要原因是其可扩展限制。如果文档横跨几个服务器,事务将会很难实施以及性能。
MongoDB4.0 事务简介
Mongodb4.0引入了多文档事务的特性,mongo进行一个多文档事务,用户需要创建一个 Session
,然后在 Session
上开启事务,提交事务。通过 startTransaction/ CRUD / commitTransaction 三段式来进行。
try (ClientSession clientSession = client.startSession()) {
clientSession.startTransaction();
collection.insertOne(clientSession, docOne);
collection.insertOne(clientSession, docTwo);
clientSession.commitTransaction();
}
Session
Session
是 MongoDB 3.6 版本引入的概念,引入这个特性主要就是为实现多文档事务做准备。Session
本质上就是一个「上下文」。
在以前的版本,MongoDB 只管理单个操作的上下文,mongod
服务进程接收到一个请求,为该请求创建一个上下文 (源码里对应 OperationContext
),然后在服务整个请求的过程中一直使用这个上下文,内容包括,请求耗时统计、请求占用的锁资源、请求使用的存储快照等信息。有了 Session
之后,就可以让多个请求共享一个上下文,让多个请求产生关联,从而有能力支持多文档事务。
每个 Session
包含一个唯一的标识 lsid,在 4.0 版本里,用户的每个请求可以指定额外的扩展字段,主要包括:
- lsid : 请求所在 Session 的 ID, 也称 logic session id
- txnNmuber : 请求对应的事务号,事务号在一个 Session 内必须单调递增
- stmtIds : 对应请求里每个操作(以insert为例,一个insert命令可以插入多个文档)操作ID
实际上,用户在使用事务时,是不需要理解这些细节,MongoDB Driver 会自动处理,Driver 在创建 Session
时分配 lsid,接下来这个 Session
里的所以操作,Driver 会自动为这些操作加上 lsid,如果是事务操作,会自动带上 txnNumber。
值得一提的是,Session
lsid 可以通过调用 startSession
命令让 server 端分配,也可以客户端自己分配,这样可以节省一次网络开销;而事务的标识,MongoDB 并没有提供一个单独的 startTransaction
的命令,txnNumber 都是直接由 Driver 来分配的,Driver 只需保证一个 Session 内,txnNumber 是递增的,server 端收到新的事务请求时,会主动的开始一个新事务。
MongoDB不适用的应用场景
综合来看MongoDB没有事务机制,不能很好地满足许多复杂业务,更多的是当做一种工具,去实现某些局部、零散的需求,提高效率,而MySQL有完善的理论,可以应对绝大部分业务场景,更适合去服务各种实际应用和业务。
MongoDB适用的应用场景
1. 弱结构很适合第三方信息的抓取,不需要为各种来源设计表结构,直接存储,极大的减少了数据库设计维护的工作量。
2. 存取灵活适合于一些随时存取,结构化要求又不高的业务场景,比如日志文件、数据分析处理等
3. 键值对是接近很多有匹配关系业务的真实应用场景,如物流(订单、点到点)、游戏(玩家对应的装备)、社交(用户之间的关系和动态)等,都能直接匹配,高效存取。