学习课程:尚硅谷Redis6
目录
NoSQL简介
NoSQL概述
NoSQL(Not Only SQL),意即“不仅仅是SQL”,泛指非关系型数据库
NoSQL不依赖于业务逻辑方式存储,而以简单的key-value模式存储,因此大大的增加了数据库的扩展能力
NoSQL的特点
1、不遵循SQL的规则
2、不支持ACID(并不是不支持事务,只是不支持ACID)
3、远超于SQL的性能
适用场景
1、对数据高并发的读写
2、海量数据的读写
3、对数据的可扩展性的
NoSQL不适用场景
1、需要事务支持
2、基于sql的结构化查询存储,处理复杂的关系,需要即席查询
几种常见的NoSQL数据库
Memcache
1、数据都在内存中,一般不持久化
2、支持简单的key-value数据结构,支持类型单一
3、一般作为缓存数据库辅助持久化数据库
Redis
1、几乎包含Memcache的绝大数功能
2、数据在内存中,支持持久化,可以用来备份恢复
3、除了支持key-value之外,还有多种数据结构,例如list、set、hash、zset等
4、一般作为缓存数据库辅助持久化数据库
MongoDB
1、高性能、开源、模式自由的文档型数据库
2、数据都在内存中,如果内存不足,吧不常用的数据保存到硬盘中
3、虽然是key-value模式,但是对value(尤其json)提供了丰富的查询功能
4、支持二进制数据及大型对象
5、可以根据数据的特点替代RDBMS,成为独立的数据库。或者配合RDBMS,存储特定的数据
Redis
Redis的底层
Redis的底层采用单线程+多路IO复用
举例说明:
假设在火车站买票的时候需要托靠黄牛(倒票的人),这时候有三个人分别找黄牛帮忙买票,黄牛在火车站买票是单线程的,因为只有他一个人在跟火车站交易。但是在买票过程中,这需要票的这三个人不需要一直等待,他们可以去做其他的事情,等黄牛买到某个人需要的票时 ,就通知那个人来取,比如买到了到深圳的票,就会通知2号过来取,这就是多路IO复用
Redis的五大数据类型
1、String类型
String类型的数据结构是简单动态字符串。是可以修改的字符串,内部实现类似于Java中的ArrayList,采用预分配冗余空间的方式来减少频繁内存的频繁分配。
如图所示,为字符串预分配的空间是capacity,一般要高于字符串的实际长度len。在字符串内存小于1M时,扩容时会按内存大小成倍扩容,但是大于1M以后,每次扩容只扩大1M,其内存分配上限是512M。
一些key键操作
1、set key value 向数据库中保存key-value键值对
2、keys * 查看数据库中有多少个键值对
3、exists key 查询当前键是否存在 1表示存在 0表示不存在
4、type key 查询当前key对应value的类型
5、del key 删除此键值对
6、unlink key 根据value选择非阻塞删除,仅将keys将keyspace元数据中删除,真正的删除会在后续异步操作
7、expire key second 给此键值对设置生命周期,单位为秒
8、ttl key 查看此键值对的是否过期 -1永不过期,-2已结过期,其他大于0的值是剩余时间
9、select index 切换数据库(默认在0)
10、dbsize 查看当前数据库有多少个键值对
11、flushdb 清空当前库
12、flushall 通杀所有的库
13、get key 查看此键值对的value
14、append key value 在此键值对后面拼接value,返回值是拼接完成后键值对value的长度
15、strlen key 查看此键值对的长度
16、setnx key value 向库中添加键值对(set 和 setnx 的区别:set key 如果该key存在,就覆盖原来的value,setnx key 如果该key存在就不添加,不存在才会添加)
17、incr/decr key 该键值对的value值加/减1(value得是数字类型的) 具有原子性!!!!
18、incrby/decrby key value 该键值对的value值加/减value值
19、mset <key> <value> <key> <value> <key> <value> 同时添加多个键值对到库中
20、mget <key> <key> <key> 同时查询多个键值对的value
21、getrange <key> <起始位置> <结束位置> 查询该键值value从起始位置到结束位置的值
22、getset <key> <value2> 查询该键值对的值,并把原value的值替换新的value2值,返回值是原来value的值
2、List类型
简介
List类型简单介绍就是一个键对应多个值。
Redis列表的是一个简单的字符串列表,按照插入顺序排序,可以在头部或者尾部添加值。
其底层是一个双向链表,对两端的操作非常高效,但是通过索引操作中间的节点性能很差。
常用命令
1、lpush/rpush <key> <value> <value> <value> 从左边或者右边插入一个或者多个值
2、lrange <key> <起始位置> <结束位置> 查询该键值对从起始位置到结束位置的元素(0,-1)表示查询所有元素
3、lpop/rpop <key> 从该键值对的左边/右边移除一个元素,当所有value移除完,该键也消失
4、rpoplpush <k1> <k2> 从k1中右边拿出一个元素添加到k2的左边
5、lindex <key> <index> 查看该键值对第index个元素
6、llen <key> 查询该键值对value的List长度
7、linsert <key> before/after <value> <newvalue> 在该键值对的某个元素前/后插入一个新的元素
数据结构
List的数据结构是快速链表quickList。
当元素较少时,会使用一块连续的内存,这个结构是zipList,也就是压缩链表。它将所有的元素紧挨着存储,就是用一块连续的内存空间。
当有大量元素时,zipList就会链接成为quickList。
Redis把zipList和quickList结合起来,就是把多个zipList采用双向指针链接起来,形成quickList,这样就会既能有高效的插入删除性能,也不会出现太多冗余的空间。普通链表的附加指针空间太大,比如一个链表存储的是int类型数据,但是需要加上pre 和 next 两个指针,就会浪费存储空间。
3、Set类型
简介
Redis set 对外提供的功能与 List 类似,是一个列表功能。区别在于 Set 可以自动排重,当你需要存储一个列表数据,同时又不希望列表中存储重复数据时,Set 就是一个非常好的选择。Set还提供判断某个元素是否在 Set 集合内的接口,这是 List 所不能做到的。
Set 是 string 类型的无序集合,底层是一个 value 为 null 的 hash 表,所以添加、删除、查找的复杂度都是 O(1)。
常用命令
1、sadd <k> <v1> <v2> <v3> … 向库中添加 set 集合,键为 k,元素为 v1、v2、v3…
2、smembers <key> 查询该键值对存储的 set 集合有哪些元素
3、sismenmber <k> <v> 查询该 set 集合中是否存在该元素
4、scard <key> 查询该 set 集合中多少个元素
5、srem <k> <v1> … 删除集合中的v1…
6、spop <k> 从集合中随机弹出一个元素,元素全部弹完,集合 key 也消失
7、srandmember <key> <n> 随机从该 set 集合中查询 n 个元素,但集合内部元素不减少
8、smove <k1> <k2> <v> 把 k1 键值对中集合的元素 v 取出放到 k2 键值对 set 集合中
9、sinter <k1> <k2> 查询两个 set 集合中的交集元素
10、sunion <k1> <k2> 查询两个 set 集合中的并集元素
11、sdiff <k1> <k2> 查询两个 set 集合中的元素的差集(k1 中有而 k2 没有的)
数据结构
Set 数据结构是 dict 字典,字典使用哈希表实现的。
Java 中的 HashSet 的内部实现是 HashMap,只不过所有的 value 都指向同一个对象。Redis 的 set 结构也是一样,它的内部也使用 hash 结构,所有的 value 都指向同一个内部值。
4、Hash
简介
Redis hash 是一个键值对集合。
Redis hash 是一个 string 类型的 filed 和 value 的映射表,hash 特别适合用于存储对象,类似Java 中的 Map<String,Object>。
如图中所示,value 中有 field 和 value,这样就可以存储对象的属性和属性值。
常用命令
1、hset <key> <field><value> 给 key 集合中的 field 键赋值为 value
2、hget <key> <field> 查询 key 集合中 field 键对应的值
3、hmset <key> <f1> <v1> <f2> <v2>… 批量添加键值对到库中
4、hexists <key> <field> 查询 key 集合中是否存在field键
5、hkeys <key>查询 key 集合中所有的键
6、hvals <key>查询 key 集合中有哪些 value 值
7、hincrby <key> <field> <increment> 将 key 集合中 filed 键的 value 增加 increment
8、hsetnx <key><field><value>向库中添加键值对,如果已经存在就不进行添加
数据结构
Hash 类型对应的数据结构有两种:zipList 和 hashTable。当 filed-value 长度较短且个数较少时,使用 zipList,否则使用 hashTable。
5、zset类型
简介
Redis 有序集合 zset 与普通集合 set 非常相似,是一个没有重复元素的字符串集合。
不同之处是有序集合的每个成员都关联了一个评分(score),这个评分被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复的。
常用命令
1、zadd <key> <s1> <v1> <s2><v2>… 向库中key集合中添加评分分别为s1、s2…的值v1、v2…
2、zrange <key> <start> <stop> (withscores) 查询key集合中从start到stop的value(带着分数显示)
3、zrangebyscore <key> <min> <max> (withscores)查询key集合中分数从min 到 max 区间的值
4、zrevrangebyscore <key> <max> <min> 跟上述查询一样,顺序颠倒
5、zincrby <key> <n> <value> 给key集合中value值的评分加上n
6、zrem <key> <v>删除可以集合中的v
7、zcount <key> <min><max>查询key集合中分数从min到max的value有多少个
8、zrank <key> <vlaue>查询key集合中的value,根据评分排序显示
数据结构
zset是Redis提供的一种非常特别的数据结构,一方面它等价于Java的数据结构Map<String,Double>,可以给每个元素value赋予一个权重score,另一方面它又类似于TreeSet,内部的元素会按照权重score进行排序,可以得到每个元素的名次。还可以通过score的范围来获取元素的列表。
zset底层使用了两个数据结构
(1)hash,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
(2)跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。