笔记参考url:
http://www.runoob.com/mongodb/mongodb-tutorial.html
nosql is short for not only sql;
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
分布式系统
分布式系统(distributed system)由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。
分布式系统是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。
因此,网络和分布式系统之间的区别更多的在于高层软件(特别是操作系统),而不是硬件。
分布式系统可以应用在在不同的平台上如:Pc、工作站、局域网和广域网上等。
NoSQL一词最早出现于1998年,是Carlo Strozzi开发的一个轻量、开源、不提供SQL功能的关系数据库。
2009年在亚特兰大举行的"no:sql(east)"讨论会是一个里程碑,其口号是"select fun, profit from real_world where relational=false;"。因此,对NoSQL最普遍的解释是"非关联型的",强调Key-Value Stores和文档数据库的优点,而不是单纯的反对RDBMS。
RDBMS :Relational Database Management System
CAP定理(CAP theorem)
在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer's theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
一致性(Consistency) (所有节点在同一时间具有相同的数据)
可用性(Availability) (保证每个请求不管成功或者失败都有响应)
分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)
BASE
BASE:Basically Available, Soft-state, Eventually Consistent。 由 Eric Brewer 定义。
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
BASE是NoSQL数据库通常对可用性及一致性的弱要求原则:
Basically Availble --基本可用
Soft-state --软状态/柔性事务。 "Soft state" 可以理解为"无连接"的, 而 "Hard state" 是"面向连接"的
Eventual Consistency --最终一致性 最终一致性, 也是是 ACID 的最终目的。
ACID vs BASE
ACID BASE
原子性(Atomicity) 基本可用(Basically Available)
一致性(Consistency) 软状态/柔性事务(Soft state)
隔离性(Isolation) 最终一致性 (Eventual consistency)
持久性 (Durable)
安装:
1,下载:
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz
2,tar -zxvf xxx
3,mv xxx /data/server/xxx
4,mkdir -p /data/db
启动
$dir/bin/mongod
连接
$dir/bin/mongo
SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键
MongoDB的默认数据库为"db",该数据库存储在data目录中。
MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限。
显示所有数据库:
show dbs;
连接指定数据库:
use local;
显示当前数据库:
db
数据库名可以是满足以下条件的任意UTF-8字符串(4)。
不能是空字符串("")。
不得含有' '(空格)、.、$、/、\和\0 (空字符)。
应全部小写。
最多64字节。
保留的数据库名和特殊意义:
admin:root用户库,添加后获取所有权限。特定数据库权限只能从这个库运行,比如列出所有的数据库或者关闭服务器。
local:不可复制。
config:当分片设置时,config在内部使用,用于保存分片的相关信息。
下表列出了 RDBMS 与 MongoDB 对应的术语:
RDBMS MongoDB
数据库 数据库
表格 集合
行 文档
列 字段
表联合 嵌入文档
主键 主键 (MongoDB 提供了 key 为 _id )
数据库服务和客户端
Mysqld/Oracle mongod
mysql/sqlplus mongo
需要注意的是:
文档中的键/值对是有序的。
文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
MongoDB区分类型和大小写。
MongoDB的文档不能有重复的键。
文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
文档键命名规范:
键不能含有\0 (空字符)。这个字符用来表示键的结尾。
.和$有特别的意义,只有在特定环境下才能使用。
以下划线"_"开头的键是保留的(不是严格要求的)。
集合存在于数据库中,集合没有固定的结构
当第一个文档插入时,集合就会被创建。
合法的集合名
集合名不能是空字符串""。
集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
集合名不能以"system."开头,这是为系统集合保留的前缀。
用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
capped collections
Capped collections 就是固定大小的collection。
它有很高的性能以及队列过期的特性(过期按照插入的顺序). 有点和 "RRD" 概念类似。
Capped collections是高性能自动的维护对象的插入顺序。它非常适合类似记录日志的功能 和标准的collection不同,你必须要显式的创建一个capped collection, 指定一个collection的大小,单位是字节。collection的数据存储空间值提前分配的。
要注意的是指定的存储大小包含了数据库的头信息。
db.createCollection("mycoll", {capped:true, size:100000})
在capped collection中,你能添加新的对象。
能进行更新,然而,对象不会增加存储空间。如果增加,更新就会失败 。
数据库不允许进行删除。使用drop()方法删除collection所有的行。
注意: 删除之后,你必须显式的重新创建这个collection。
在32bit机器中,capped collection最大存储为1e9( 1X109)个字节。
元数据
集合命名空间 描述
dbname.system.namespaces 列出所有名字空间。
dbname.system.indexes 列出所有索引。
dbname.system.profile 包含数据库概要(profile)信息。
dbname.system.users 列出所有可访问数据库的用户。
dbname.local.sources 包含复制对端(slave)的服务器信息和状态。
MongoDB 数据类型
数据类型 描述
String 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
Integer 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。
Boolean 布尔值。用于存储布尔值(真/假)。
Double 双精度浮点值。用于存储浮点值。
Min/Max keys 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。
Arrays 用于将数组或列表或多个值存储为一个键。
Timestamp 时间戳。记录文档修改或添加的具体时间。
Object 用于内嵌文档。
Null 用于创建空值。
Symbol 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
Date 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
Object ID 对象 ID。用于创建文档的 ID。
Binary Data 二进制数据。用于存储二进制数据。
Code 代码类型。用于在文档中存储 JavaScript 代码。
Regular expression 正则表达式类型。用于存储正则表达式。
创建数据库:runoob
use runoob
db.runoob.insert({"name":"hehe"}) 需要插入新的数据,才能 show dbs 进行显示。
删除数据库
show dbs; #查看
use runoob; #选择
db.dropDatabase(); #操作
show dbs; #确认
删除集合runoob.site
use runoob;
show tables;
db.site.drop();
show tables;
MongoDB 插入文档
BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。
以下文档可以存储在 MongoDB 的 runoob 数据库 的 col 集合中:
db.col.insert({title:'MongoDB 教程',
description:'MongoDB是一个nosql数据库'})
查看插入的文档:
db.col.find()
将数据定义变量:
document=({"title":"MongoDB教程","tags":["mongodb","database","NoSQL"],"likes":100})
执行插入语句:
方法一:
db.col.insert(document);
方法二:
db.col.save(document); #不指定_id,同insert;指定_id,则根据_id进行更新。
3.2后增加的插入方法:
db.col.insertOne(); #插入单条
db.col.insertMany(); #插入多条
var document=db.col.insertMany([{name:"hehe"},{name:"haha"}]);
document
MongoDB 更新文档
update方法:
db.col.update(
<query>
<update>
{
upsert:<boolean>,
multi:<boolean>,
writeConcern:<document>
}
)
upsert:可选,如目标记录不存在,是否插入.默认为false,不插入。
multi:可选,默认false,只更新找到的第一条记录。true为更新所有。
writeConcern:可选,抛出异常的级别。
db.col.insert({name:"hehe",age:15});
db.col.update({name:"hehe"},{$set:{name:"hehe2"}})
db.col.find().pretty() #json格式展示结果
db.col.update({name:"haha"},{$set:{age:100}},{multi:true});
save方法:
通过_id进行替换。
db.col.save(
<document>
{
writeConcern:<document>
}
)
替换 _id 为 56064f89ade2f21f36b03136 的文档数据
db.col.save(
{_id:ObjectId("56064f89ade2f21f36b03136"),name:"hehe2"}
)
只更新第一条记录:
db.col.update({"count":{$gt : 1}},{$set : {"test2":"OK"}});
全部更新:
db.col.update({name:"hehe"},{$set:{age:100}},flase,true});
只
全部添加进去:
db.col.update({name:"hehe"},{$inc:{age:1}},true,true);
$inc 语意:在原有基础上增加值。
删除文档:
db.collection.remove(
<query>,
<justOne>
)
2.6版本以后,语法格式如下:
db.col.remove(
<query>,
{
justOne:<boolean>,
writeConcern:<document>
}
)
query:可选,过滤条件
justOne:可选,ture或1,则只删除一个文档
writeConcern:可选,抛出异常的级别
删除所有name:"hehe"的文档
db.col.remove({name:"hehe"});
删除第一条找到的name:"hehe"的文档
db.col.remove({name:"hehe"},1);
清空集合:
db.col.remove({});
MongoDB 查询文档
db.col.find(query,projection)
query:可选,指定查询条件。
projection:可选,结果过滤.
db.col.find().pretty():格式化结果。
db.col.findOne() #只返回一个结果
逻辑表达式:
小于:$lt
小于等于:$lte
大于:$gt
大于等于:$gte
不等于:$ne
查找 col中name:"hehe" or age:35的学生
db.col.find({$or:[{name:"hehe"},{age:35}]});
查找 col中age>32 并且 name:"hehe" or name:"xixi"
db.col.find({age:{$gt:32},$or:[{name:"hehe"},{name:"xixi"}]});
查找col中32<age<=35的学生。
db.col.find({age:{$gt:32,$lte:35}});
结果中只显示年龄,并且不显示_id:
db.col.find({},{age:1,_id:0});
MongoDB $type 操作符(只支持对应的数字)
过滤name为数字类型的数据:
db.col.find({name:{$type:1}});
类型 数字 备注
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
MongoDB Limit与Skip方法
查询col的前两条数据
db.col.find().limit(2);
查询col的第2条数据。
db.col.find().limit(1).skip(1);
执行顺序 sort再skip再limit
MongoDB 排序
db.col.find().sort({key:1});
按年龄倒序:
db.col.find().sort({age:-1}); #字符串大于任何数字
MongoDB 索引
1,特殊结构
2,对一列或多列进行排序
3,被存储在易于遍历的集合中
name字段创建生序索引:
db.col.ensureIndex({name:1});
name,age创建符合索引:
db.col.ensureIndex({name:1,age:-1});
ensureIndex() 接收可选参数,可选参数列表如下:
Parameter Type Description
background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。
unique Boolean 建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
name string 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
dropDups Boolean 在建立唯一索引时是否删除重复记录,指定 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.
后台创建age正序索引:
db.col.ensureIndex({age:1},{background:true});
查看索引:
db.col.getIndexes();
删除索引:
db.col.dropIndex({name:1}); #需指明key和顺序。
MongoDB 聚合
db.col.aggregate(aggregate_opt);
计算name同名的个数:
db.col.aggregate([{$group:{_id:"$name",count:{$sum:1}}}]);
select name,count(1) from col group by name;
计算同名的年龄总和:
db.col.aggregate([{$group:{_id:"$name",count:{$sum:"$age"}}}]);
db.col.aggregate([{$group:{_id:"$name",count:{$first:"$age"}}}]);
db.col.aggregate([{$group:{_id:"$name",count:{$last:"$age"}}}]);
db.col.aggregate([{$group:{_id:"$name",count:{$addToSet:"$age"}}}]); #
db.col.aggregate([{$group:{_id:"$name",count:{$push:"$age"}}}]);
常用聚合函数:
表达式 描述 实例
$sum 计算总和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 计算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 获取集合中所有文档对应值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 获取集合中所有文档对应值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 在结果文档中插入值到一个数组中。结果以逗号分隔。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 在结果文档中插入值到一个数组中,但不创建副本。结果以逗号分隔。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根据资源文档的排序获取第一个文档数据。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根据资源文档的排序获取最后一个文档数据 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])
管道的概念
聚合管道,结果传递,只能处理当前文档。
db.col.aggregate([{$project:{name:1,age:1,_id:0}}]);
对于10<age<=80的用户,根据name分组统计个数:$match+$group
db.col.aggregate([
{$match:{age:{$gt:10,$lte:80}}},
{$group:{_id:"$name",count:{$sum:1}}}]);
$skip过滤掉前2个文档:
db.col.aggregate({$skip:2});
常用的管道流操作:
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
MongoDB 复制(副本集) #待补充
MongoDB 分片
另一种集群,满足存储和读写吞吐要求,通过在多台机器分割数据实现。
为什么实用分片:
复制所有的写入操作到主节点
延时的敏感数据在主节点查询
单个副本集限制在12个节点
当请求量巨大时会出现内存不足。
本地磁盘不足
垂直扩展价格昂贵
集群结构分布:
query routers:前端路由,让整个集群像一个数据库,前端应用透明使用。
config server:mongod实例,存ClusterMetadata,包括chunk信息
shard:存储实际数据块,实际环境一个shard server角色由几台机器组成一个replica set 承担,防止单点故障。
分片实例
分片结构端口分布如下:
Shard Server 1:27020
Shard Server 2:27021
Shard Server 3:27022
Shard Server 4:27023
Config Server :27100
Route Process:40000