这次的夏令营好像周数有点多,那就再说说redis,之后的项目要求也需要集成redis这个非关系型数据库

Redis是什么?

Redis(Remote Dictionary Server ),即远程字典服务。

是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis能干什么?

  1. 内存存储、持久化,内存是断电即失的,所以需要持久化(RDB、AOF)
  2. 高效率、用于高速缓冲
  3. 发布订阅系统
  4. 地图信息分析
  5. 计时器、计数器(eg:浏览量)
  6. 。。。

特性

  1. 多样的数据类型
  2. 持久化
  3. 集群
  4. 事务

环境搭建(略)

基础知识

redis默认有16个数据库
image.png
默认使用的第0个;
16个数据库为:DB 0~DB 15 默认使用DB 0 ,可以使用select n切换到DB n,dbsize可以查看当前数据库的大小,与key数量相关。

  1. 127.0.0.1:6379> config get databases # 命令行查看数据库数量databases
  2. 1) "databases"
  3. 2) "16"
  4. 127.0.0.1:6379> select 8 # 切换数据库 DB 8
  5. OK
  6. 127.0.0.1:6379[8]> dbsize # 查看数据库大小
  7. (integer) 0
  8. 不同数据库之间 数据是不能互通的,并且dbsize 是根据库中key的个数。
  9. 127.0.0.1:6379> set name sakura
  10. OK
  11. 127.0.0.1:6379> SELECT 8
  12. OK
  13. 127.0.0.1:6379[8]> get name # db8中并不能获取db0中的键值对。
  14. (nil)
  15. 127.0.0.1:6379[8]> DBSIZE
  16. (integer) 0
  17. 127.0.0.1:6379[8]> SELECT 0
  18. OK
  19. 127.0.0.1:6379> keys *
  20. "counter:rand_int"
  21. "mylist"
  22. "name"
  23. "key:rand_int"
  24. "myset:rand_int"
  25. 127.0.0.1:6379> DBSIZE # sizekey个数相关
  26. (integer) 5

keys * :查看当前数据库中所有的key。
flushdb:清空当前数据库中的键值对。
flushall:清空所有数据库的键值对。
Redis是单线程的,Redis是基于内存操作的。
所以Redis的性能瓶颈不是CPU,而是机器内存和网络带宽。
那么为什么Redis的速度如此快呢,性能这么高呢?QPS达到10W+
Redis为什么单线程还这么快?

  • 误区1:高性能的服务器一定是多线程的?
  • 误区2:多线程(CPU上下文会切换!)一定比单线程效率高!

核心:Redis是将所有的数据放在内存中的,所以说使用单线程去操作效率就是最高的,多线程(CPU上下文会切换:耗时的操作!),对于内存系统来说,如果没有上下文切换效率就是最高的,多次读写都是在一个CPU上的,在内存存储数据情况下,单线程就是最佳的方案。

五大数据类型

Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。

Redis-key

在redis中无论什么数据类型,在数据库中都是以key-value形式保存,通过进行对Redis-key的操作,来完成对数据库中数据的操作。

下面学习的命令:

  • exists key:判断键是否存在
  • del key:删除键值对
  • move key db:将键值对移动到指定数据库
  • expire key second:设置键值对的过期时间
  • type key:查看value的数据类型
  1. 127.0.0.1:6379> keys * # 查看当前数据库所有key
  2. (empty list or set)
  3. 127.0.0.1:6379> set name qinjiang # set key
  4. OK
  5. 127.0.0.1:6379> set age 20
  6. OK
  7. 127.0.0.1:6379> keys *
  8. 1) "age"
  9. 2) "name"
  10. 127.0.0.1:6379> move age 1 # 将键值对移动到指定数据库
  11. (integer) 1
  12. 127.0.0.1:6379> EXISTS age # 判断键是否存在
  13. (integer) 0 # 不存在
  14. 127.0.0.1:6379> EXISTS name
  15. (integer) 1 # 存在
  16. 127.0.0.1:6379> SELECT 1
  17. OK
  18. 127.0.0.1:6379[1]> keys *
  19. 1) "age"
  20. 127.0.0.1:6379[1]> del age # 删除键值对
  21. (integer) 1 # 删除个数
  22. 127.0.0.1:6379> set age 20
  23. OK
  24. 127.0.0.1:6379> EXPIRE age 15 # 设置键值对的过期时间
  25. (integer) 1 # 设置成功 开始计数
  26. 127.0.0.1:6379> ttl age # 查看key的过期剩余时间
  27. (integer) 13
  28. 127.0.0.1:6379> ttl age
  29. (integer) 11
  30. 127.0.0.1:6379> ttl age
  31. (integer) 9
  32. 127.0.0.1:6379> ttl age
  33. (integer) -2 # -2 表示key过期,-1表示key未设置过期时间
  34. 127.0.0.1:6379> get age # 过期的key 会被自动delete
  35. (nil)
  36. 127.0.0.1:6379> keys *
  37. "name"
  38. 127.0.0.1:6379> type name # 查看value的数据类型
  39. string

关于TTL命令

Redis的key,通过TTL命令返回key的过期时间,一般来说有3种:

  1. 当前key没有设置过期时间,所以会返回-1.
  2. 当前key有设置过期时间,而且key已经过期,所以会返回-2.
  3. 当前key有设置过期时间,且key还没有过期,故会返回key的正常剩余时间.

关于重命名RENAMERENAMENX

  1. RENAME key newkey修改 key 的名称
  2. RENAMENX key newkey仅当 newkey 不存在时,将 key 改名为 newkey 。

String(字符串)

普通的set、get直接略过。

常用命令及其示例:

APPEND key value: 向指定的key的value后追加字符串

  1. 127.0.0.1:6379> set msg hello
  2. OK
  3. 127.0.0.1:6379> append msg " world"
  4. (integer) 11
  5. 127.0.0.1:6379> get msg
  6. hello world

DECR/INCR key: 将指定key的value数值进行+1/-1(仅对于数字)

  1. 127.0.0.1:6379> set age 20
  2. OK
  3. 127.0.0.1:6379> incr age
  4. (integer) 21
  5. 127.0.0.1:6379> decr age
  6. (integer) 20

INCRBY/DECRBY key n: 按指定的步长对数值进行加减

  1. 127.0.0.1:6379> INCRBY age 5
  2. (integer) 25
  3. 127.0.0.1:6379> DECRBY age 10
  4. (integer) 15

INCRBYFLOAT key n: 为数值加上浮点型数值

  1. 127.0.0.1:6379> INCRBYFLOAT age 5.2
  2. 20.2

STRLEN key: 获取key保存值的字符串长度

  1. 127.0.0.1:6379> get msg
  2. hello world
  3. 127.0.0.1:6379> STRLEN msg
  4. (integer) 11

GETRANGE key start end: 按起止位置获取字符串(闭区间,起止位置都取)

  1. 127.0.0.1:6379> get msg
  2. hello world
  3. 127.0.0.1:6379> GETRANGE msg 3 9
  4. lo worl

SETRANGE key offset value:用指定的value 替换key中 offset开始的值

  1. 127.0.0.1:6379> set msg hello
  2. OK
  3. 127.0.0.1:6379> setrange msg 2 hello
  4. (integer) 7
  5. 127.0.0.1:6379> get msg
  6. "hehello"
  7. 127.0.0.1:6379> set msg2 world
  8. OK
  9. 127.0.0.1:6379> setrange msg2 2 ww
  10. (integer) 5
  11. 127.0.0.1:6379> get msg2
  12. "wowwd"

GETSET key value: 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。

  1. 127.0.0.1:6379> GETSET msg test
  2. hello world

SETNX key value: 仅当key不存在时进行set

  1. 127.0.0.1:6379> SETNX msg test
  2. (integer) 0
  3. 127.0.0.1:6379> SETNX name sakura
  4. (integer) 1

SETEX key seconds value: set 键值对并设置过期时间

  1. 127.0.0.1:6379> setex name 10 root
  2. OK
  3. 127.0.0.1:6379> get name
  4. (nil)

MSET key1 value1 [key2 value2..]: 批量set键值对

  1. 127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3
  2. OK

MSETNX key1 value1 [key2 value2..]: 批量设置键值对,仅当参数中所有的key都不存在时执行

  1. 127.0.0.1:6379> MSETNX k1 v1 k4 v4
  2. (integer) 0

MGET key1 [key2..]: 批量获取多个key保存的值

  1. 127.0.0.1:6379> MGET k1 k2 k3
  2. 1) v1
  3. 2) v2
  4. 3) v3

PSETEX key milliseconds value: 和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间

String类似的使用场景:value除了是字符串还可以是数字,用途举例:

  • 计数器
  • 统计多单位的数量:uid:123666:follow 0
  • 粉丝数
  • 对象存储缓存

List(列表)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
首先我们列表,可以经过规则定义将其变为队列、栈、双端队列等。
image.png
正如图Redis中List是可以进行双端操作的,所以命令也就分为了LXXX和RLLL两类,有时候L也表示List例如LLEN

  • LPUSH/RPUSH key value1[value2..]从左边/右边向列表中PUSH值(一个或者多个)。
  • LRANGE key start end 获取list 起止元素(索引从左往右 递增)
  • LPUSHX/RPUSHX key value 向已存在的列名中push值(一个或者多个)
  • LINSERT key BEFORE|AFTER pivot value 在指定列表元素的前/后 插入value
  • LLEN key 查看列表长度
  • LINDEX key index 通过索引获取列表元素
  • LSET key index value 通过索引为元素设值
  • LPOP/RPOP key 从最左边/最右边移除值 并返回
  • RPOPLPUSH source destination 将列表的尾部(右)最后一个值弹出,并返回,然后加到另一个列表的头部
  • LTRIM key start end 通过下标截取指定范围内的列表
  • LREM key count value List中是允许value重复的 count > 0:从头部开始搜索 然后删除指定的value 至多删除count个 count < 0:从尾部开始搜索… count = 0:删除列表中所有的指定value。
  • BLPOP/BRPOP key1[key2] timout 移出并获取列表的第一个/最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
  • BRPOPLPUSH source destination timeout 和RPOPLPUSH功能相同,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

代码示例:

  1. ---------------------------LPUSH---RPUSH---LRANGE--------------------------------
  2. 127.0.0.1:6379> LPUSH mylist k1 # LPUSH mylist=>{1}
  3. (integer) 1
  4. 127.0.0.1:6379> LPUSH mylist k2 # LPUSH mylist=>{2,1}
  5. (integer) 2
  6. 127.0.0.1:6379> RPUSH mylist k3 # RPUSH mylist=>{2,1,3}
  7. (integer) 3
  8. 127.0.0.1:6379> get mylist # 普通的get是无法获取list值的
  9. (error) WRONGTYPE Operation against a key holding the wrong kind of value
  10. 127.0.0.1:6379> LRANGE mylist 0 4 # LRANGE 获取起止位置范围内的元素
  11. "k2"
  12. "k1"
  13. "k3"
  14. 127.0.0.1:6379> LRANGE mylist 0 2
  15. "k2"
  16. "k1"
  17. "k3"
  18. 127.0.0.1:6379> LRANGE mylist 0 1
  19. "k2"
  20. "k1"
  21. 127.0.0.1:6379> LRANGE mylist 0 -1 # 获取全部元素
  22. "k2"
  23. "k1"
  24. "k3"
  25. ---------------------------LPUSHX---RPUSHX-----------------------------------
  26. 127.0.0.1:6379> LPUSHX list v1 # list不存在 LPUSHX失败
  27. (integer) 0
  28. 127.0.0.1:6379> LPUSHX list v1 v2
  29. (integer) 0
  30. 127.0.0.1:6379> LPUSHX mylist k4 k5 # mylist 左边 PUSH k4 k5
  31. (integer) 5
  32. 127.0.0.1:6379> LRANGE mylist 0 -1
  33. "k5"
  34. "k4"
  35. "k2"
  36. "k1"
  37. "k3"
  38. ---------------------------LINSERT--LLEN--LINDEX--LSET----------------------------
  39. 127.0.0.1:6379> LINSERT mylist after k2 ins_key1 # k2元素后 插入ins_key1
  40. (integer) 6
  41. 127.0.0.1:6379> LRANGE mylist 0 -1
  42. "k5"
  43. "k4"
  44. "k2"
  45. "ins_key1"
  46. "k1"
  47. "k3"
  48. 127.0.0.1:6379> LLEN mylist # 查看mylist的长度
  49. (integer) 6
  50. 127.0.0.1:6379> LINDEX mylist 3 # 获取下标为3的元素
  51. "ins_key1"
  52. 127.0.0.1:6379> LINDEX mylist 0
  53. "k5"
  54. 127.0.0.1:6379> LSET mylist 3 k6 # 将下标3的元素 set值为k6
  55. OK
  56. 127.0.0.1:6379> LRANGE mylist 0 -1
  57. "k5"
  58. "k4"
  59. "k2"
  60. "k6"
  61. "k1"
  62. "k3"
  63. ---------------------------LPOP--RPOP--------------------------
  64. 127.0.0.1:6379> LPOP mylist # 左侧(头部)弹出
  65. "k5"
  66. 127.0.0.1:6379> RPOP mylist # 右侧(尾部)弹出
  67. "k3"
  68. ---------------------------RPOPLPUSH--------------------------
  69. 127.0.0.1:6379> LRANGE mylist 0 -1
  70. "k4"
  71. "k2"
  72. "k6"
  73. "k1"
  74. 127.0.0.1:6379> RPOPLPUSH mylist newlist # mylist的最后一个值(k1)弹出,加入到newlist的头部
  75. "k1"
  76. 127.0.0.1:6379> LRANGE newlist 0 -1
  77. "k1"
  78. 127.0.0.1:6379> LRANGE mylist 0 -1
  79. "k4"
  80. "k2"
  81. "k6"
  82. ---------------------------LTRIM--------------------------
  83. 127.0.0.1:6379> LTRIM mylist 0 1 # 截取mylist中的 0~1部分
  84. OK
  85. 127.0.0.1:6379> LRANGE mylist 0 -1
  86. "k4"
  87. "k2"
  88. 初始 mylist: k2,k2,k2,k2,k2,k2,k4,k2,k2,k2,k2
  89. ---------------------------LREM--------------------------
  90. 127.0.0.1:6379> LREM mylist 3 k2 # 从头部开始搜索 至多删除3 k2
  91. (integer) 3
  92. 删除后:mylist: k2,k2,k2,k4,k2,k2,k2,k2
  93. 127.0.0.1:6379> LREM mylist -2 k2 #从尾部开始搜索 至多删除2 k2
  94. (integer) 2
  95. 删除后:mylist: k2,k2,k2,k4,k2,k2
  96. ---------------------------BLPOP--BRPOP--------------------------
  97. mylist: k2,k2,k2,k4,k2,k2
  98. newlist: k1
  99. 127.0.0.1:6379> BLPOP newlist mylist 30 # newlist中弹出第一个值,mylist作为候选
  100. "newlist" # 弹出
  101. "k1"
  102. 127.0.0.1:6379> BLPOP newlist mylist 30
  103. "mylist" # 由于newlist空了 mylist中弹出
  104. "k2"
  105. 127.0.0.1:6379> BLPOP newlist 30
  106. (30.10s) # 超时了
  107. 127.0.0.1:6379> BLPOP newlist 30 # 我们连接另一个客户端向newlistpushtest, 阻塞被解决。
  108. "newlist"
  109. "test"
  110. (12.54s)

小结

  • list实际上是一个链表,before Node after , left, right 都可以插入值
  • 如果key不存在,则创建新的链表
  • 如果key存在,新增内容
  • 如果移除了所有值,空链表,也代表不存在
  • 在两边插入或者改动值,效率最高!修改中间元素,效率相对较低

应用:
消息排队!消息队列(Lpush Rpop),栈(Lpush Lpop)

Set(集合)

Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

  • SADD key member1[member2..] 向集合中无序增加一个/多个成员
  • SCARD key 获取集合的成员数
  • SMEMBERS key 返回集合中所有的成员
  • SISMEMBER key member 查询member元素是否是集合的成员,结果是无序的
  • SRANDMEMBER key [count] 随机返回集合中count个成员,count缺省值为1
  • SPOP key [count] 随机移除并返回集合中count个成员,count缺省值为1
  • SMOVE source destination member 将source集合的成员member移动到destination集合
  • SREM key member1[member2..] 移除集合中一个/多个成员
  • SDIFF key1[key2..] 返回所有集合的差集 key1- key2 - …
  • SDIFFSTORE destination key1[key2..] 在SDIFF的基础上,将结果保存到集合中(覆盖)。不能保存到其他类型key噢!
  • SINTER key1 [key2..] 返回所有集合的交集
  • SINTERSTORE destination key1[key2..] 在SINTER的基础上,存储结果到集合中。覆盖
  • SUNION key1 [key2..] 返回所有集合的并集
  • SUNIONSTORE destination key1 [key2..] 在SUNION的基础上,存储结果到及和张。覆盖
  • SSCAN KEY [MATCH pattern] [COUNT count] 在大量数据环境下,使用此命令遍历集合中元素,每次遍历部分

代码示例

  1. ---------------SADD--SCARD--SMEMBERS--SISMEMBER--------------------
  2. 127.0.0.1:6379> SADD myset m1 m2 m3 m4 # myset中增加成员 m1~m4
  3. (integer) 4
  4. 127.0.0.1:6379> SCARD myset # 获取集合的成员数目
  5. (integer) 4
  6. 127.0.0.1:6379> smembers myset # 获取集合中所有成员
  7. "m4"
  8. "m3"
  9. "m2"
  10. "m1"
  11. 127.0.0.1:6379> SISMEMBER myset m5 # 查询m5是否是myset的成员
  12. (integer) 0 # 不是,返回0
  13. 127.0.0.1:6379> SISMEMBER myset m2
  14. (integer) 1 # 是,返回1
  15. 127.0.0.1:6379> SISMEMBER myset m3
  16. (integer) 1
  17. ---------------------SRANDMEMBER--SPOP----------------------------------
  18. 127.0.0.1:6379> SRANDMEMBER myset 3 # 随机返回3个成员
  19. "m2"
  20. "m3"
  21. "m4"
  22. 127.0.0.1:6379> SRANDMEMBER myset # 随机返回1个成员
  23. "m3"
  24. 127.0.0.1:6379> SPOP myset 2 # 随机移除并返回2个成员
  25. "m1"
  26. "m4"
  27. set还原到{m1,m2,m3,m4}
  28. ---------------------SMOVE--SREM----------------------------------------
  29. 127.0.0.1:6379> SMOVE myset newset m3 # mysetm3成员移动到newset集合
  30. (integer) 1
  31. 127.0.0.1:6379> SMEMBERS myset
  32. "m4"
  33. "m2"
  34. "m1"
  35. 127.0.0.1:6379> SMEMBERS newset
  36. "m3"
  37. 127.0.0.1:6379> SREM newset m3 # newset中移除m3元素
  38. (integer) 1
  39. 127.0.0.1:6379> SMEMBERS newset
  40. (empty list or set)
  41. 下面开始是多集合操作,多集合操作中若只有一个参数默认和自身进行运算
  42. setx=>{m1,m2,m4,m6}, sety=>{m2,m5,m6}, setz=>{m1,m3,m6}
  43. -----------------------------SDIFF------------------------------------
  44. 127.0.0.1:6379> SDIFF setx sety setz # 等价于setx-sety-setz
  45. "m4"
  46. 127.0.0.1:6379> SDIFF setx sety # setx - sety
  47. "m4"
  48. "m1"
  49. 127.0.0.1:6379> SDIFF sety setx # sety - setx
  50. "m5"
  51. -------------------------SINTER---------------------------------------
  52. 共同关注(交集)
  53. 127.0.0.1:6379> SINTER setx sety setz # setxsetysetx的交集
  54. "m6"
  55. 127.0.0.1:6379> SINTER setx sety # setx sety的交集
  56. "m2"
  57. "m6"
  58. -------------------------SUNION---------------------------------------
  59. 127.0.0.1:6379> SUNION setx sety setz # setx sety setz的并集
  60. "m4"
  61. "m6"
  62. "m3"
  63. "m2"
  64. "m1"
  65. "m5"
  66. 127.0.0.1:6379> SUNION setx sety # setx sety 并集
  67. "m4"
  68. "m6"
  69. "m2"
  70. "m1"
  71. "m5"

Hash(哈希)

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Set就是一种简化的Hash,只变动key,而value使用默认值填充。可以将一个Hash表作为一个对象进行存储,表中存放对象的信息。

  • HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。重复设置同一个field会覆盖,返回0
  • HMSET key field1 value1 [field2 value2..] 同时将多个 field-value (域-值)对设置到哈希表 key 中。
  • HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。
  • HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。
  • HGET key field value 获取存储在哈希表中指定字段的值
  • HMGET key field1 [field2..] 获取所有给定字段的值
  • HGETALL key 获取在哈希表key 的所有字段和值
  • HKEYS key 获取哈希表key中所有的字段
  • HLEN key 获取哈希表中字段的数量
  • HVALS key 获取哈希表中所有值
  • HDEL key field1 [field2..] 删除哈希表key中一个/多个field字段
  • HINCRBY key field n 为哈希表 key 中的指定字段的整数值加上增量n,并返回增量后结果 一样只适用于整数型字段
  • HINCRBYFLOAT key field n 为哈希表 key 中的指定字段的浮点数值加上增量 n。
  • HSCAN key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的键值对。

代码示例

  1. ------------------------HSET--HMSET--HSETNX----------------
  2. 127.0.0.1:6379> HSET studentx name sakura # studentx哈希表作为一个对象,设置namesakura
  3. (integer) 1
  4. 127.0.0.1:6379> HSET studentx name gyc # 重复设置field进行覆盖,并返回0
  5. (integer) 0
  6. 127.0.0.1:6379> HSET studentx age 20 # 设置studentxage20
  7. (integer) 1
  8. 127.0.0.1:6379> HMSET studentx sex 1 tel 15623667886 # 设置sex1tel15623667886
  9. OK
  10. 127.0.0.1:6379> HSETNX studentx name gyc # HSETNX 设置已存在的field
  11. (integer) 0 # 失败
  12. 127.0.0.1:6379> HSETNX studentx email 12345@qq.com
  13. (integer) 1 # 成功
  14. ----------------------HEXISTS--------------------------------
  15. 127.0.0.1:6379> HEXISTS studentx name # name字段在studentx中是否存在
  16. (integer) 1 # 存在
  17. 127.0.0.1:6379> HEXISTS studentx addr
  18. (integer) 0 # 不存在
  19. -------------------HGET--HMGET--HGETALL-----------
  20. 127.0.0.1:6379> HGET studentx name # 获取studentxname字段的value
  21. "gyc"
  22. 127.0.0.1:6379> HMGET studentx name age tel # 获取studentxnameagetel字段的value
  23. "gyc"
  24. "20"
  25. "15623667886"
  26. 127.0.0.1:6379> HGETALL studentx # 获取studentx中所有的field及其value
  27. "name"
  28. "gyc"
  29. "age"
  30. "20"
  31. "sex"
  32. "1"
  33. "tel"
  34. "15623667886"
  35. "email"
  36. "12345@qq.com"
  37. --------------------HKEYS--HLEN--HVALS--------------
  38. 127.0.0.1:6379> HKEYS studentx # 查看studentx中所有的field
  39. "name"
  40. "age"
  41. "sex"
  42. "tel"
  43. "email"
  44. 127.0.0.1:6379> HLEN studentx # 查看studentx中的字段数量
  45. (integer) 5
  46. 127.0.0.1:6379> HVALS studentx # 查看studentx中所有的value
  47. "gyc"
  48. "20"
  49. "1"
  50. "15623667886"
  51. "12345@qq.com"
  52. -------------------------HDEL--------------------------
  53. 127.0.0.1:6379> HDEL studentx sex tel # 删除studentx 中的sextel字段
  54. (integer) 2
  55. 127.0.0.1:6379> HKEYS studentx
  56. "name"
  57. "age"
  58. "email"
  59. -------------HINCRBY--HINCRBYFLOAT------------------------
  60. 127.0.0.1:6379> HINCRBY studentx age 1 # studentxage字段数值+1
  61. (integer) 21
  62. 127.0.0.1:6379> HINCRBY studentx name 1 # 非整数字型字段不可用
  63. (error) ERR hash value is not an integer
  64. 127.0.0.1:6379> HINCRBYFLOAT studentx weight 0.6 # weight字段增加0.6
  65. "90.8"

Hash变更的数据user name age,尤其是用户信息之类的,经常变动的信息!Hash更适合于对象的存储,Sring更加适合字符串存储!

Zset(有序集合)

不同的是每个元素都会关联一个double类型的分数(score)。redis正是通过分数来为集合中的成员进行从小到大的排序。
score相同:按字典顺序排序
有序集合的成员是唯一的,但分数(score)却可以重复。

  • ZADD key score member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
  • ZCARD key 获取有序集合的成员数
  • ZCOUNT key min max 计算在有序集合中指定区间score的成员数
  • ZINCRBY key n member 有序集合中对指定成员的分数加上增量 n
  • ZSCORE key member 返回有序集中,成员的分数值
  • ZRANK key member 返回有序集合中指定成员的索引
  • ZRANGE key start end 通过索引区间返回有序集合成指定区间内的成员
  • ZRANGEBYLEX key min max 通过字典区间返回有序集合的成员
  • ZRANGEBYSCORE key min max 通过分数返回有序集合指定区间内的成员-inf 和 +inf分别表示最小最大值,只支持开区间()
  • ZLEXCOUNT key min max 在有序集合中计算指定字典区间内成员数量
  • ZREM key member1 [member2..] 移除有序集合中一个/多个成员
  • ZREMRANGEBYLEX key min max 移除有序集合中给定的字典区间的所有成员
  • ZREMRANGEBYRANK key start stop 移除有序集合中给定的排名区间的所有成员
  • ZREMRANGEBYSCORE key min max 移除有序集合中给定的分数区间的所有成员
  • ZREVRANGE key start end 返回有序集中指定区间内的成员,通过索引,分数从高到底
  • ZREVRANGEBYSCORRE key max min 返回有序集中指定分数区间内的成员,分数从高到低排序
  • ZREVRANGEBYLEX key max min 返回有序集中指定字典区间内的成员,按字典顺序倒序
  • ZREVRANK key member 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
  • ZINTERSTORE destination numkeys key1 [key2 ..] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中,numkeys:表示参与运算的集合数,将score相加作为结果的score
  • ZUNIONSTORE destination numkeys key1 [key2..] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
  • ZSCAN key cursor [MATCH pattern] [COUNT count] 迭代有序集合中的元素(包括元素成员和元素分值)

代码示例

  1. -------------------ZADD--ZCARD--ZCOUNT--------------
  2. 127.0.0.1:6379> ZADD myzset 1 m1 2 m2 3 m3 # 向有序集合myzset中添加成员m1 score=1 以及成员m2 score=2..
  3. (integer) 2
  4. 127.0.0.1:6379> ZCARD myzset # 获取有序集合的成员数
  5. (integer) 2
  6. 127.0.0.1:6379> ZCOUNT myzset 0 1 # 获取score [0,1]区间的成员数量
  7. (integer) 1
  8. 127.0.0.1:6379> ZCOUNT myzset 0 2
  9. (integer) 2
  10. ----------------ZINCRBY--ZSCORE--------------------------
  11. 127.0.0.1:6379> ZINCRBY myzset 5 m2 # 将成员m2score +5
  12. "7"
  13. 127.0.0.1:6379> ZSCORE myzset m1 # 获取成员m1score
  14. "1"
  15. 127.0.0.1:6379> ZSCORE myzset m2
  16. "7"
  17. --------------ZRANK--ZRANGE-----------------------------------
  18. 127.0.0.1:6379> ZRANK myzset m1 # 获取成员m1的索引,索引按照score排序,score相同索引值按字典顺序顺序增加
  19. (integer) 0
  20. 127.0.0.1:6379> ZRANK myzset m2
  21. (integer) 2
  22. 127.0.0.1:6379> ZRANGE myzset 0 1 # 获取索引在 0~1的成员
  23. "m1"
  24. "m3"
  25. 127.0.0.1:6379> ZRANGE myzset 0 -1 # 获取全部成员
  26. "m1"
  27. "m3"
  28. "m2"
  29. testset=>{abc,add,amaze,apple,back,java,redis} score均为0
  30. ------------------ZRANGEBYLEX---------------------------------
  31. 127.0.0.1:6379> ZRANGEBYLEX testset - + # 返回所有成员
  32. "abc"
  33. "add"
  34. "amaze"
  35. "apple"
  36. "back"
  37. "java"
  38. "redis"
  39. 127.0.0.1:6379> ZRANGEBYLEX testset - + LIMIT 0 3 # 分页 按索引显示查询结果的 0,1,2条记录
  40. "abc"
  41. "add"
  42. "amaze"
  43. 127.0.0.1:6379> ZRANGEBYLEX testset - + LIMIT 3 3 # 显示 3,4,5条记录
  44. "apple"
  45. "back"
  46. "java"
  47. 127.0.0.1:6379> ZRANGEBYLEX testset (- [apple # 显示 (-,apple] 区间内的成员
  48. "abc"
  49. "add"
  50. "amaze"
  51. "apple"
  52. 127.0.0.1:6379> ZRANGEBYLEX testset [apple [java # 显示 [apple,java]字典区间的成员
  53. "apple"
  54. "back"
  55. "java"
  56. -----------------------ZRANGEBYSCORE---------------------
  57. 127.0.0.1:6379> ZRANGEBYSCORE myzset 1 10 # 返回score [1,10]之间的的成员
  58. "m1"
  59. "m3"
  60. "m2"
  61. 127.0.0.1:6379> ZRANGEBYSCORE myzset 1 5
  62. "m1"
  63. "m3"
  64. --------------------ZLEXCOUNT-----------------------------
  65. 127.0.0.1:6379> ZLEXCOUNT testset - +
  66. (integer) 7
  67. 127.0.0.1:6379> ZLEXCOUNT testset [apple [java
  68. (integer) 3
  69. ------------------ZREM--ZREMRANGEBYLEX--ZREMRANGBYRANK--ZREMRANGEBYSCORE--------------------------------
  70. 127.0.0.1:6379> ZREM testset abc # 移除成员abc
  71. (integer) 1
  72. 127.0.0.1:6379> ZREMRANGEBYLEX testset [apple [java # 移除字典区间[apple,java]中的所有成员
  73. (integer) 3
  74. 127.0.0.1:6379> ZREMRANGEBYRANK testset 0 1 # 移除排名0~1的所有成员
  75. (integer) 2
  76. 127.0.0.1:6379> ZREMRANGEBYSCORE myzset 0 3 # 移除score [0,3]的成员
  77. (integer) 2
  78. testset=> {abc,add,apple,amaze,back,java,redis} score均为0
  79. myzset=> {(m1,1),(m2,2),(m3,3),(m4,4),(m7,7),(m9,9)}
  80. ----------------ZREVRANGE--ZREVRANGEBYSCORE--ZREVRANGEBYLEX-----------
  81. 127.0.0.1:6379> ZREVRANGE myzset 0 3 # score递减排序,然后按索引,返回结果的 0~3
  82. "m9"
  83. "m7"
  84. "m4"
  85. "m3"
  86. 127.0.0.1:6379> ZREVRANGE myzset 2 4 # 返回排序结果的 索引的2~4
  87. "m4"
  88. "m3"
  89. "m2"
  90. 127.0.0.1:6379> ZREVRANGEBYSCORE myzset 6 2 # score递减顺序 返回集合中分数在[2,6]之间的成员
  91. "m4"
  92. "m3"
  93. "m2"
  94. 127.0.0.1:6379> ZREVRANGEBYLEX testset [java (add # 按字典倒序 返回集合中(add,java]字典区间的成员
  95. "java"
  96. "back"
  97. "apple"
  98. "amaze"
  99. -------------------------ZREVRANK------------------------------
  100. 127.0.0.1:6379> ZREVRANK myzset m7 # score递减顺序,返回成员m7索引
  101. (integer) 1
  102. 127.0.0.1:6379> ZREVRANK myzset m2
  103. (integer) 4
  104. mathscore=>{(xm,90),(xh,95),(xg,87)} 小明、小红、小刚的数学成绩
  105. enscore=>{(xm,70),(xh,93),(xg,90)} 小明、小红、小刚的英语成绩
  106. -------------------ZINTERSTORE--ZUNIONSTORE-----------------------------------
  107. 127.0.0.1:6379> ZINTERSTORE sumscore 2 mathscore enscore # mathscore enscore进行合并 结果存放到sumscore
  108. (integer) 3
  109. 127.0.0.1:6379> ZRANGE sumscore 0 -1 withscores # 合并后的score是之前集合中所有score的和
  110. "xm"
  111. "160"
  112. "xg"
  113. "177"
  114. "xh"
  115. "188"
  116. 127.0.0.1:6379> ZUNIONSTORE lowestscore 2 mathscore enscore AGGREGATE MIN # 取两个集合的成员score最小值作为结果的
  117. (integer) 3
  118. 127.0.0.1:6379> ZRANGE lowestscore 0 -1 withscores
  119. "xm"
  120. "70"
  121. "xg"
  122. "87"
  123. "xh"
  124. "93"

应用案例:

  1. set排序 存储班级成绩表 工资表排序!
  2. 普通消息,1.重要消息 2.带权重进行判断
  3. 排行榜应用实现,取Top N测试

转载自:https://www.cnblogs.com/kylinxxx/p/13770063.html