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