MongoDB
1、简介
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源NoSql数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
CAP定理
在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer’s theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
- 一致性(Consistency) (所有节点在同一时间具有相同的数据)
- 可用性(Availability) (保证每个请求不管成功或者失败都有响应)
- 分区容错性(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
- CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
- CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
- AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
常用NoSql数据库
类型 | 部分代表 | 特点 |
---|---|---|
列存储 | Hbase,Cassandra,Hypertable | 顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。 |
文档存储 | MongoDB,CouchDB | 文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。 |
key-value存储 | Tokyo Cabinet / Tyrant,Berkeley DB,MemcacheDB,Redis | 可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能) |
图存储 | Neo4J,FlockDB | 图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。 |
对象存储 | db4o,Versant | 通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。 |
xml数据库 | Berkeley DB XML,BaseX | 高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。 |
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
分布式系统(distributed system)由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。
特点:
- MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。
- 你可以在MongoDB记录中设置任何属性的索引
- 分片:如果负载增加,它可以分布在计算机网络中的其他节点上。
RDBMS与Mongodb对应术语:
RDBMS | MongoDB |
---|---|
数据库 | 数据库 |
表格 | 集合 |
行 | 文档 |
列 | 字段 |
表联合 | 嵌入文档 |
主键 | 主键 (MongoDB 提供了 key 为 _id ) |
2、安装
下载网址:https://www.mongodb.com/try/download/community-kubernetes-operator
windows命令:
1 | net start MongoDB |
linux安装:
需要openssl:
1 | yum install libcurl openssl |
官网下载
解压
1 | tar -zxvf mongodb-linux-x86_64-rhel70-7.0.5.tgz |
移动:
1 | [root@iZgw02lo2mc5w2j7dgdd5zZ swap]# ls |
创建logs、data目录
1 | [root@iZgw02lo2mc5w2j7dgdd5zZ mongodb]# mkdir data logs |
创建log文件
1 | [root@iZgw02lo2mc5w2j7dgdd5zZ mongodb]# ls |
bin目录下创建配置文件
1 | [root@iZgw02lo2mc5w2j7dgdd5zZ bin]# pwd |
配置文件内容
1 | 数据文件存放目录 |
启动常用参数
参数 | 说明 | 取值示例 |
---|---|---|
dbpath | mongodb数据文件存储路径(指定数据库目录) | /usr/local/mongodb/data |
logpath | mongod的日志路径(指定日志文件目录) | /usr/local/mongodb/logs/mongodb.log |
logappend | 日志使用追加代替覆盖 | true |
fork | 以守护程序的方式启用,即在后台运行 | true |
bind_ip | IP地址 | 0.0.0.0 |
port | 端口 | 27107 |
auth | 认证模式,此处为true,需要设置账号密码 | false |
启动数据库,ctrl+c停止进程
1 | ./mongod -f mongodb.conf |
添加命令到环境变量
1 | vim /etc/profile |
默认端口为27017
3、连接
mongodbshell下载
https://www.mongodb.com/try/download/shell
将认证模式改为false,auth=false
创建超管账号:
1 | use admin |
验证
1 | use admin |
Mongodb连接URI:
1 | mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] |
连接示例
1 | mongodb://jiuzhao:password@localhost:27017/filesDB |
4、常用命令
4.1、数据库
“show dbs” 命令可以显示所有数据的列表。
1 | show dbs |
执行 “db” 命令可以显示当前数据库对象或集合。
1 | db |
运行”use“命令,可以连接到一个指定的数据库,若没有该数据库,则创建该数据库。
1 | use local |
保留的,可以直接访问这些有特殊作用的数据库:
- admin: 从权限的角度来看,这是”root”数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
删除数据库
1 | db.dropDatabase() |
4.2、集合
集合有俩种,一种固定大小(Capped collections),一种不固定大小。
集合命名规范:
- 集合名不能是空字符串””。
- 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
- 集合名不能以”system.”开头,这是为系统集合保留的前缀。
- 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
Capped collections 就是固定大小的collection。
它有很高的性能以及队列过期的特性(过期按照插入的顺序). 有点和 “RRD” 概念类似。
Capped collections 是高性能自动的维护对象的插入顺序。它非常适合类似记录日志的功能和标准的 collection 不同,你必须要显式的创建一个capped collection,指定一个 collection 的大小,单位是字节。collection 的数据存储空间值提前分配的。
Capped collections 可以按照文档的插入顺序保存到集合中,而且这些文档在磁盘上存放位置也是按照插入顺序来保存的,所以当我们更新Capped collections 中文档的时候,更新后的文档不可以超过之前文档的大小,这样话就可以确保所有文档在磁盘上的位置一直保持不变。
由于 Capped collection 是按照文档的插入顺序而不是使用索引确定插入位置,这样的话可以提高增添数据的效率。MongoDB 的操作日志文件 oplog.rs 就是利用 Capped Collection 来实现的。
要注意的是指定的存储大小包含了数据库的头信息。
创建集合
1 | db.createCollection("mycoll", {capped:true, size:100000}) |
删除集合
1 | db.collection.drop() |
4.3、文档
文档是一组键值(key-value)对(即 BSON)。
注意:
- 文档中的键/值对是有序的。
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
- 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
- MongoDB区分类型和大小写。
- MongoDB的文档不能有重复的键。
键的命名规范:
- 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
- .和$有特别的意义,只有在特定环境下才能使用。
- 以下划线”_”开头的键是保留的(不是严格要求的)。
Mongodb数据类型:
数据类型 | 描述 |
---|---|
String | 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 |
Integer | 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 |
Boolean | 布尔值。用于存储布尔值(真/假)。 |
Double | 双精度浮点值。用于存储浮点值。 |
Min/Max keys | 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 |
Array | 用于将数组或列表或多个值存储为一个键。 |
Timestamp | 时间戳。记录文档修改或添加的具体时间。 |
Object | 用于内嵌文档。 |
Null | 用于创建空值。 |
Symbol | 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
Date | 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。 |
Object ID | 对象 ID。用于创建文档的 ID。 |
Binary Data | 二进制数据。用于存储二进制数据。 |
Code | 代码类型。用于在文档中存储 JavaScript 代码。 |
Regular expression | 正则表达式类型。用于存储正则表达式。 |
插入文档
1 | db.COLLECTION_NAME.insert(document) |
3.2版本之后新增db.collection.insertOne() 和 db.collection.insertMany()
1 | db.collection.insertOne( |
参数:
- document:要写入的文档。
- writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
- ordered:指定是否按顺序写入,默认 true,按顺序写入。
更新文档
1 | db.collection.update( |
参数说明:
- query : update的查询条件,类似sql update查询内where后面的。
- update : update的对象和一些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set后面的
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
删除文档
1 | db.collection.remove( |
参数说明:
- query :(可选)删除的文档的条件。
- justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
- writeConcern :(可选)抛出异常的级别。
条件操作符
MongoDB条件操作符有:
- (>) 大于 - $gt
- (<) 小于 - $lt
- (>=) 大于等于 - $gte
- (<= ) 小于等于 - $lte
例子:
1 | db.col.find({likes : {$gt : 100}}) |
$type操作符
MongoDB 中可以使用的类型如下表所示:
类型 | 数字 | 备注 |
---|---|---|
Double | 1 | |
String | 2 | |
Object | 3 | |
Array | 4 | |
Binary data | 5 | |
Undefined | 6 | 已废弃。 |
Object id | 7 | |
Boolean | 8 | |
Date | 9 | |
Null | 10 | |
Regular Expression | 11 | |
JavaScript | 13 | |
Symbol | 14 | |
JavaScript (with scope) | 15 | |
32-bit integer | 16 | |
Timestamp | 17 | |
64-bit integer | 18 | |
Min key | 255 | Query with -1 . |
Max key | 127 |
1 | db.col.find({"title" : {$type : 2}}) |
limit语法
number限定获取记录条数
1 | db.COLLECTION_NAME.find().limit(NUMBER) |
skip语法
接受一个数字参数作为跳过的记录条数。
默认为0。
1 | db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER) |
sort排序
使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
1 | db.COLLECTION_NAME.find().sort({KEY:1}) |
5、索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
MongoDB使用 createIndex() 方法来创建索引。
语法
1 | db.collection.createIndex(keys, options) |
语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。
createIndex() 接收可选参数,可选参数列表如下:
Parameter | Type | Description |
---|---|---|
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 “background” 默认值为false。 |
unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. |
name | string | 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 |
dropDups | Boolean | 3.0+版本已废弃。在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false. |
sparse | Boolean | 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false. |
expireAfterSeconds | integer | 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 |
v | index version | 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 |
weights | document | 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 |
default_language | string | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 |
language_override | string | 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language. |
查看集合索引
1 | db.col.getIndexes() |
查看集合索引大小
1 | db.col.totalIndexSize() |
删除所有索引
1 | db.col.dropIndexes() |
删除集合指定索引
1 | db.col.dropIndex("索引名称") |
失效时间设置
利用ttl集合,索引关键字段必须是 Date 类型。
1 | db.col.createIndex({"createDate": 1},{expireAfterSeconds: 180}) |
索引子文档
1 | db.users.createIndex({"address.city":1,"address.state":1,"address.pincode":1}) |
全文检索
全文检索对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。
2.6之后默认开启
1 | { |
索引不能被以下的查询使用:
- 正则表达式及非操作符,如 $nin, $not, 等。
- 算术运算符,如 $mod, 等。
- $where 子句
索引范围:
- 集合中索引不能超过64个
- 索引名的长度不能超过128个字符
- 一个复合索引最多可以有31个字段
6、负载
6.1、分片
什么是分片技术?
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
组件:
Shard:
用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障
Config Server:
mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
Query Routers:
前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。
6.2、复制
什么是复制?
复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
从硬件故障和服务中断中恢复数据。
7、SpringBoot整合
官网:https://docs.spring.io/spring-data/data-mongodb/reference/mongodb/template-api.html
引入依赖
1 | <dependency> |
俩种访问Mongodb方式:MongoRepository和MongoTemplate。
1 | Person p = new Person("Joe", 34); |
使用Query
和Criteria
类来表达查询
1 |
|