NoSQL
1998,NoREL
2009,NoSQL
非关系型
分布式
不提供ACID

NoSQL
简单数据模型
元数据和应用数据分离
弱一致性

优势:
避免不必要的复杂性
高吞吐量
高水平扩展能力和低端硬件集群
不使用对象-关系映射
劣势:
不支持ACID
功能简单
没有统一的数据查询模型

NewSQL
NoSQL <-->SQL(日志,锁,缓冲区管理)
Clustrix,GenieDB,ScaleArc,ScaleBase,NimbusDB

NoSQL:
键值存储
列式数据库
文档数据库
图存数据库

SQL:

缓存数据库系统:

C,A:SQL
C,P:悲观加锁
A,P:DNS

数据一致性模型:强一致性,弱一致性,最终一致性

数据一致性的实现技术:

Quorum系统NRW策略:
N:总的副本数
R:完成读操作所需要读取的最少副本数
W:完成写操作所需要写入的最小副本数
强一致性:R+W>N
Mysql:一主两从
R+W<=N:最多只能保证最终一致性:

两段式提交策略:2PC(Two Phase Commit Protocol)

有两类几点:
一类为协调者
一类为事务参与者

两段:
第一阶段:请求阶段
第二阶段:提交阶段

时间戳策略

Paxos策略

向量时钟

NoSQL的数据存储模型:
键值模型:(key-value存储)
优点:查找速度快
缺点:数据无结构,通常只被当做字符产或二进制数据
应用场景,内容缓存
实例:Redis,Dynamo

列式模型:
数据模型:数据按列存储,将同一列数据存在一起;
优点:查找迅速、可扩展性强、易于实现分布式;
缺点:功能相对SQL有限
应用场景:分布式文件系统或分布式存储
实例:Bigtable,Cassandra,HBase,Hypertable

文档模型:
数据模型:与键值模型类似,value指向结构化数据;
优点:数据格式要求不严格,无需事先定义结构
缺点:查询性能不高,缺乏统一查询语法
应用场景:web应用
实例:MongoDB,CouchDB

图式模型:
数据模型:图结构模型
优点:利用图结构相关算法提高性能,并足特殊场景应用需求
应用场景:社交网络,推荐系统,关系图谱
实例Neo4J

www.nosql-database.org

面向collection的数据库
数据库:但数据库无须创建
表:行<-->集合:文档
集合无须事先定义

{
name:Tom
Age:30
Gender:Male
Books:{
first:one puppet
second:two puppet
}
}

{
name:Jerry
Age:15
Gender:Female
Books {
first:none cat
second:many money
}
Birthday:2013-10-28
}

C/S:
mongod
mongo --> mongod
mongo > use testdb
mongo> db.mycollection.insert()

安装配置mongodb:
yum install mongo-10gen-2.4.6-mongodb_x86_64.rpm mongo-10gen-server-2.4.6-mongodb_x86_64.rpm

mkdir -pv /mongodb/data
chown -R mongod.mongod /mongodb/data

vim /etc/mongod.conf
dbpath=/mongodb/data

service mongod start

http://172.16.100.15:28017

mongo

use testdb
show dbs
show collections
db.testcoll.insert({Name:"Tom"})
show collections
db.testcoll.find()
db.testcoll.insert({Name:"Jerry"})
db.testcoll.find()
db.testcoll.stats()
db.testcoll.drop()
show collections
for(i=1;i<=100;i++) db.testcoll.insert({Name:"User"+i,Age:i,Gender:M,PreferBooks:["first book","Second book"]})
db.testcoll.find()
it
it
db.testcoll.find().limit(3)
db.testcoll.remove({Age:10})
db.testcoll.remove({Name:"User14"})
db.testcoll.update({Name:"User12"},{$set:{Age:32}})
db.testcoll.count()
db.testcoll.find({Age:{$gte:93})
db.testcoll.find({Age:{$gte:93},{Name:1,Age:1})
db.testcoll.find({$and:[{Age:{$gt:61}},{Age:{$lt:80}}]})
db.testcoll.insert({Name:"User101",Age:101,Gender:"F",Address:"Beijing,China"})
db.testcoll.find({Address:{$exists:true}})
db.testcoll.update({Age:{$gt:80}},{$set:{Gender:"F"}},{multi:true})
db.testcoll.update({Name:"User92"},{$unset:{PreferBooks:""}})

cd /mongodb/data/

db.COLL_NAME.METHOO
常用方法:
C:insert()
R:find()
U:update()
D:remove()

用JSON格式的文档:
insert({})
find({},{})
limit()
sort()
count()
skip()
update({},{},{multi:true})
remove({})

Database,Collection,Document

比较操作、逻辑操作、元素操作

比较操作:
$lt
$lte
$in
$nin
$gt
$gte

{Field:{$opeartor: VALUE}}

逻辑操作:
$and
$or
$not
$nor

{$operator [{},{},{}]}

db.testcoll.find({$or:[{NAME:"User12"},{Age:{$gt:80}}]})

1000W:80

索引的优点:
1.大大减少了服务器需要扫描的数据量
2.索引可以帮助服务器避免排序或使用临时表
3.索引可以将随机I/O转换顺序I/O

关系型数据库索引设计与优化

索引:三星
一星:索引如果能将相关的记录放置在一起
二星:索引中数据的存储顺序与查找标准中顺序一致
三星:如果索引中包含查询中所需要的全部数据;(覆盖索引)

索引类别:
顺序索引
散列索引:将索引映射至散列桶上,映射是通过散列函数进行的;

评估索引的标准:
访问类型
访问时长
插入时长
删除时长
空间开销

顺序索引:
聚集索引:如果某记录文件中的记录顺序是按照对应的搜索码指定的顺序排序;聚集索引也称为主索引;
非聚集索引:搜索码中的指定的次序与次序与记录文件中的不一致
有聚集索引的数据文件,也叫作索引顺序文件
根据索引中是否为每个记录相应地创建索引项,稠密索引和稀疏索引

多级索引:

辅助索引必须是稠密索引

B+树索引:
Balance Tree:平衡树

顺序索引的特性:
全值匹配:Name="user12"
匹配最左前缀:Name LIKE "User1%",无效:Name LIKE "%User1%"
匹配列前缀:Name LIKE "User1%",无效:Name LIKE "%User1%"
匹配范围值
精确匹配某一列并范围匹配另一列
只访问索引的查询

组合索引

散列索引:
散列函数:
分布随机
分布均匀
适用场景:
精确值匹配: =,IN(),<=>

MySQL:全文索引:fulltext
sphinx,lucene

空间索引:必须使用空间索引函数获取相应的查询的结果

主键,惟一键

MySQL:创建索引
create index index_name on table(col1,...)
alter table add index
alter table drop index
drop index index_name from table
show indexes from table

use testdb
db.testcoll.find()
db.testcoll.ensuerIndex({Name:1})
db.testcoll.getIndexes()
db.testcoll.ensureIndex({Name:"hashed"})
db.testcoll.dropIndex("Name_hashed")
db.testcoll.dropIndex({Name:1})
db.testcoll.find({Name:"User19"}).explain()
db.testcoll.ensureIndex({Name:1,Age:1},{unique:true})

Replica Set:
复制集,副本集
名称(复制集群名称)

172.16.100.15 node1
172.16.100.16 node2
172.16.100.17 node3

node1:
yum install mongo-10gen-2.4.6-mongodb_x86_64.rpm mongo-10gen-server-2.4.6-mongodb_x86_64.rpm

mkdir -pv /mongodb/data
chown -R mongod.mongod /mongodb/data

vim /etc/mongod.conf
dbpath=/mongodb/data
replSet = testrs0
rest = true

service mongod start

mongo

rs.help()
rs.initiate()
rs.status()
db.isMaster()
rs.add("172.16.100.16:27017")
rs.status()
rs.add("172.16.100.17:27017")
db.isMaster()
use testdb
db.testcoll.insert({Name:"test",Age:50,Gender:"F"})
db.testcoll.find()
db.printReplicationInfo()
mycfg=rs.conf()
mycfg.members[0].priority=2(设定节点的优先级)
rs.reconfig(mycfg)

node2:
yum install mongo-10gen-2.4.6-mongodb_x86_64.rpm mongo-10gen-server-2.4.6-mongodb_x86_64.rpm

mkdir -pv /mongodb/data
chown -R mongod.mongod /mongodb/data

vim /etc/mongod.conf
dbpath=/mongodb/data
replSet = testrs0
rest = true

service mongod start

mogo

rs.slaveOk()(执行此语句才能在从节点上面操作查看)
use testdb
db.testcoll.find()
db.testcoll.insert({Name:"Tom",Age:45})(把主节点停掉之后执行此条语句查看是否同步)

node3:
yum install mongo-10gen-2.4.6-mongodb_x86_64.rpm mongo-10gen-server-2.4.6-mongodb_x86_64.rpm

mkdir -pv /mongodb/data
chown -R mongod.mongod /mongodb/data

vim /etc/mongod.conf
dbpath=/mongodb/data
replSet = testrs0
rest = true

service mongod start

mogo

rs.slaveOk()
use testdb
db.testcoll.find()

触发重新选举:
优先级为0的节点

配置shared分布式集群:
172.16.100.15 mongos
172.16.100.16 config server
172.16.100.17 shard1
172.16.100.18 shard2

config server:

vim /etc/mongod.conf
dbpath=/mongodb/data
configsvr = true

service mogod start

mogo --host 172.16.100.15
mongos>sh.status
mongos>sh.addShared("172.16.100.17:27017")
mongos>sh.addShared("172.16.100.18:27017")
mongos>sh.status
mongos>sh.enableSharding("testdb")
mongos>sh.shardCollection("testdb.testcoll",{Age:1,Name:1})
mongos>sh.status()
mongos>use testdb
mongos>for (i=1;i<=100000;i++) db.testcoll.insert({Name:"User"+i,Age:(i%150),Address:"#"+i+",Wenhua Road, Zhengzhou,China",PreferBooks:["book"+i,"hello world"]})
mongos>sh.status()
mongos>db.testcoll.find({Age:{$gt:85}})
mongos>sh.getBalancerState()

mongos:

vim /etc/mongod.conf
#dbpath=/mongodb/data(注释掉)
configdb = 172.16.100.16:27019

mongos -f /etc/mongod.conf

shared1:(在生产中还要加两台节点配置副本集,此实验采用单独节点)

vim /etc/mongod.conf
dbpath=/mongodb/data

service mogod start

shared2:(在生产中还要加两台节点配置副本集,此实验采用单独节点)

vim /etc/mongod.conf
dbpath=/mongodb/data

service mogod start

重复索引:
name,age,gender,preferbooks,address

name,
name,age

覆盖索引:
name,age

db.mycoll.find().hint().explain()

mysql>explain select * from table;

复制集群:
master/slave
replica set
arbiter:仅参与选举,不持有任何数据;
0优先级的节点:持有数据,参与选举,但不能成为主节点;

replSet=

shared集群:
sharding的目的:

读,写
读:不离散
写:离散

mongodb:collection级别
sharding key:collection索引

config server:元数据服务器,3台(zookeeper)
mongos:路由
shard:standalone,replica set

选择sharding key的标准:
应该在哪儿存储数据?
应该从哪儿得到希望的数据?

基本法则:
sharding key应该是主键:
sharding key应该能尽量保证避免跨分片查询

chunk:64M
rebalance:重新均衡
shareding:新增shared,移除shared

mongodump,mongorestored
mongoexport,mongoimport

mapreduce:聚合
GridFS