本文将以大数据时代的数据特点和需求为起步,引出Nosql数据库和分布式数据库,并简要介绍Nosql的数据模型、分类,以及分布式数据的CAP等原理,最后着重介绍属于Nosql数据库和分布式数据库的redis。
目前大数据时代的数据具有3V的特性:海量(Volume),多样(Variety),实时(Velocity),而目前互联网的需求在于高并发,高可扩,高性能。原本的关系型数据库难以存储海量和多样的数据,集中式的数据库难以满足高并发和高可扩的需求,
聚合模型分别有:KV键值,bson,列族,图形。
bson样例,和json样式上类似:
css
复制代码
{ name:"lemo", age:"12", address:{ city:"suzhou", country:"china", code:215000 } , scores:[ {"name":"english","grade:3.0}, {"name":"chinese","grade:2.0} ] }
列族:
图形:
不同的数据模型,分成了不同的数据库种类。
以下是该分类典型的数据库
kv键值:redis
文档型数据库(Bson格式比较多):CouchDB,MongoDB
列存储数据库:Cassandra, HBase ,分布式文件系统
图关系数据库:Neo4J, InfoGrid
关系型数据库一般是都严格遵循的。
CAP理论是说在分布式存储系统中,最多只能实现上面的两点,所有会有三种类型:
CA 传统Oracle数据库;
AP 大多数网站架构的选择 ;
CP Redis、Mongodb;
而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。注意:分布式架构的时候必须做出取舍。一致性和可用性之间取一个平衡。多余大多数web应用,其实并不需要强一致性。因此牺牲C换取P,这是目前分布式数据库产品的方向
BASE就是为了解决关系数据库强一致性引起的问题而引起的可用性降低而提出的解决方案。BASE其实是下面三个术语的缩写: 基本可用(Basically Available) 软状态(Soft state) 最终一致(Eventually consistent)
它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上改观。为什么这么说呢,缘由就在于大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,要想获得这些指标,我们必须采用另外一种方式来完成,这里BASE就是解决这个问题的办法
Redis:REmote DIctionary Server(远程字典服务器)。
Redis是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器
特点:
开启:
关闭:
perl
复制代码
#格式:keys [正则] #例如:查询所有key keys *
perl
复制代码
# 描述:判断key是否存在 # 格式:exists [key的名称] exists k1
scss
复制代码
# 格式: move [key的名称] [要迁移到的库] # 描述:将key:k1 从当前库迁移到1库,当前库key:k1不再存在 move k1 1
例子:
bash
复制代码
# 格式: expire [key的名称] [秒钟] # 描述:过期key被删除 # yw有效期2秒 expire yw 2
例子
bash
复制代码
# 格式:ttl [key的名称] # 描述:查看还有多少秒过期,-1表示永不过期,-2表示已过期
例子:
shell
复制代码
# 格式: type [key的名称]
例子:
特点:单值单value
(1)set 单个添加
shell
复制代码
# 格式:set [key名称] [值] # 其中的值,可以说String 或 数字
(2) setex 添加key的同时设置有效时间
css
复制代码
# 格式:setex [key名称] [有效时间] [值]
例子:
(3) setnx 如果key不存在,则添加key,如果已存在则不添加
bash
复制代码
# 格式:setnx [key名称] [值] # 如果添加不成功,返回0
例子:
(4) mset 批量添加
css
复制代码
# 格式:mset [key名称] [值] [key名称] [值][key名称] [值] ...
(5)msetnx 批量添加如果key不存在,则添加key,如果已存在则不添加
css
复制代码
# 格式:msetnx [key名称] [值] [key名称] [值][key名称] [值] ...
(1) del 删除key
css
复制代码
# 格式:del [key名称]
(1)value 为 字符串型
a.在字符串后面追加值
css
复制代码
# 格式: append [key名称] [追加的值]
例子:
b.范围内替换值
css
复制代码
# 格式:setrange [key名称] [替换起始下标] [替换值] # 描述:替换起始下标从0开始计算,按照替换值的长度等量替换
(2) value为数字类型
a. 加1
bash
复制代码
# 格式: incr [key名称]
b.减1
bash
复制代码
# 格式:decr [key名称]
c. 加 任意值
css
复制代码
# 格式:incrby [key名称] [任意值]
d. 减任意值
css
复制代码
# 格式:decrby [key名称] [任意值]
(1)获取单个key的值
vbnet
复制代码
# 格式:get [key名称]
(2) 获取多个key的值
css
复制代码
# 格式:mget [key名称] [key名称] ...
(3)获取key的值字符串长度
bash
复制代码
# 格式:strlen [key名称]
(4)获取key的值 字符串中部分
css
复制代码
# 格式:getrange [key名称] [起始下标] [结束下标] # 描述:获取起始下标到结束下标的值
css
复制代码
# 格式:getset [key名称] [赋值的值]
(1)lpush 将一个或多个值 value 插入到列表 key 的表头 ,若该key不存在,则创建key,并添加值
css
复制代码
# 格式: lpush [key名称] [值1] [值2] ...
(2) rpush 将一个或多个值 value 插入到列表 key 的表尾(最右边) , 如果 key 不存在,一个空列表会被创建并执行 RPUSH 操作。
css
复制代码
# 格式: rpush [key名称] [值1] [值2] ...
(3)linsert 在list某个已有值的前后再添加具体值
css
复制代码
# 格式: linsert [key] before/after [value1] [value2]
(1) lrange 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。
css
复制代码
# 格式: lrange [key名称] [start] [stop] # 注意: stop对应的下标元素是包含在内的
(2)lindex 返回列表 key 中,下标为 index 的元素。
css
复制代码
# 格式: lindex [key名称] [index]
(3) llen 返回列表 key 的长度
bash
复制代码
# 格式: llen [key名称]
(1)lpop 移除并返回列表 key 的头元素
bash
复制代码
# 格式:lpop [key名称]
(2)rpop 移除并返回列表 key 的尾元素
bash
复制代码
# 格式:rpop [key名称]
(3) lrem 根据参数 count 的值,移除列表中与参数 value 相等的元素
bash
复制代码
# 格式:lrem [key] [count] [value] # 注意:count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。 # count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。 # count = 0 : 移除表中所有与 value 相等的值。
(4) ltrim 移除区间外的值
scss
复制代码
# 格式: ltrim [key] [start] [stop] # 描述: 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。举个例子,执行命令 LTRIM list 0 2 ,表示只保留列表 list 的前三个元素,其余元素全部删除。
(1) rpoplpush 将一个列表中的尾元素弹出(移除),添加到另一个列表中表头
css
复制代码
# 格式:rpoplpush [source] [destination]
(1)lset 修改列表中某个下标的值
css
复制代码
# 格式: lset [key] [index] [value] # 描述: 将列表 key 下标为 index 的元素的值设置为 value 。
(1)sadd 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
css
复制代码
# 格式: sadd [key] [member] [member] ...
(1)smembers 查询集合中所有的值
bash
复制代码
# 格式: smembers [key]
(2)sismember 判断值是否是集合中的成员
css
复制代码
# 格式:sismember [key] [value]
(3)scard 查询集合中有多少个元素
bash
复制代码
# 格式: scard [key]
(4)srandmember 随机查询集合中指定数量的值
css
复制代码
# srandmember [key] [count查询数量]
(1)srem 删除集合中某元素
bash
复制代码
# 格式: srem key value
(2)spop 随机删除指定数量的元素
css
复制代码
# 格式:spop [key] [count]
(3)smove 将值从一个集合移动到另一个集合
css
复制代码
smove [oldkey] [newkey] [member]
(1)差集:在第一个set里面而不在后面任何一个set里面的成员
css
复制代码
sdiff [key1] [key] ...
(2)交集:所有set中共有的成员
css
复制代码
sinter [key] [key] ...
(3)并集:所有set中所有元素的集合
css
复制代码
sunion [key] [key] ...
(1)hset 添加hash键值对
css
复制代码
hset [key] [field] [value] [field] [value] ...
描述:将哈希表 hash 中域 field 的值设置为 value 。
如果给定的哈希表并不存在, 那么一个新的哈希表将被创建并执行 HSET 操作。
如果域 field 已经存在于哈希表中, 那么它的旧值将被新值 value 覆盖。
(2)hmset 添加hash多个键值对
css
复制代码
hmset [key] [field] [value] [field] [value] ...
hset也能添加多个
(3) hsetnx 当且仅当域 field 尚未存在于哈希表的情况下, 将它的值设置为 value 。
css
复制代码
hsetnx [key] [field] value
如果给定域已经存在于哈希表当中, 那么命令将放弃执行设置操作。
如果哈希表 hash 不存在, 那么一个新的哈希表将被创建并执行 HSETNX 命令。
(1)hget 查询哈希表中某个键的值
css
复制代码
hget [key] [field]
返回哈希表中给定域的值。
(2)hmget 查询哈希表中多个键的值
css
复制代码
hmget [key] [field] [field] [field]
返回哈希表 key 中,一个或多个给定域的值。
如果给定的域不存在于哈希表,那么返回一个 nil 值。
因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行 HMGET操作将返回一个只带有 nil 值的表。
(3) hgetall 返回哈希表中所有的域和值
scss
复制代码
返回哈希表 key 中,所有的域和值。 在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
(4) hlen 查询哈希表中域数量
css
复制代码
hlen [key]
(5) hexists 判断field是否在哈希表中
css
复制代码
hexists [key] [field]
(6) hkeys 查询哈希表中的所有的域
css
复制代码
hkeys [key]
(7) hvals 查询哈希表中所有域的值
css
复制代码
hvals [key]
(1)hdel 删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略
css
复制代码
hdel [key] [field] [field] ...
(1)hincrby 为哈希表 key 中的域 field 的值加上增量 increment 。
css
复制代码
hincrby [key] [field] [increment]
增量也可以为负数,相当于对给定域进行减法操作。
如果 key 不存在,一个新的哈希表被创建并执行 HINCRBY命令。
如果域 field 不存在,那么在执行命令前,域的值被初始化为 0 。
对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。
本操作的值被限制在 64 位(bit)有符号数字表示之内。
(2) hincrbyfloat 为哈希表 key 中的域 field 加上浮点数增量 increment 。
css
复制代码
hincrbyfloat [key] [field] [increment]
如果哈希表中没有域 field ,那么 HINCRBYFLOAT会先将域 field 的值设为 0 ,然后再执行加法操作。
如果键 key 不存在,那么 HINCRBYFLOAT 会先创建一个哈希表,再创建域 field ,最后再执行加法操作。
当以下任意一个条件发生时,返回一个错误: