Redis的五大基本类型

Redis的基本数据结构是非常重要的,熟练的掌握Redis的基本数据结构会为之后的Redis学习有一个坚实的基础。
本文介绍了Redis的五大基本类型和其常用命令的使用,每个命令都有具体的示例演示,帮助理解。

文章目录

  • String(字符串)
    • String的使用场景
  • List(列表)
    • List小结
  • Set(集合)
  • Hash(哈希)
    • 使用场景
  • Zset(有序集合)
    • 使用场景

String(字符串)

  • 设置值

  • 获取值

  • 获得所有的key

  • 判断某一个key是否存在

  • 向字符串的值中追加内容

  • 如果当前key不存在,就相当于set key

  • 如果当前key是存在的,那么就会在其后面追加内容

  • 获取当前key的value的长度

local:0>set name leiyujia
"OK"
local:0>get name
"leiyujia"
local:0>keys *
 1)  "name"
local:0>Exists name
"1"
local:0>append name hello
"13"
local:0>strlen name
"13"
  • 设置自动增长和自动减少
local:0>set views 0 # 设置浏览量为0
"OK"
local:0>incr views  # 浏览量+1
"1"
local:0>incr views
"2"
local:0>decr views  # 浏览量-1
"1"
local:0>decr views
"0"
  • 设置带步长的自动增长和自动减少
local:0>incrby views 10 #设置自动增长 步长为10
"10"
local:0>incrby views 10
"20"
local:0>decrby views 10
"10"
  • 获取范围内的value值
local:0>set name hello,leiyujia
"OK"
local:0>getrange name 0 5  #获取0-5位置的字符串,注意在Redis中字符串的下标也是从0开始的
"hello,"
  • 替换
local:0>set name aaaa
"OK"
local:0>setrange name 1 b #将字符串1位置的字符替换为b
"4"
local:0>get name
"abaa"

存在不存在设置

  • setex(set whit expire): 设置过期时间
  • setnx(set if not expire)::不存在再设置
local:0>set name leiyujia # 设置name的值是leiyujia
"OK"
local:0>setnx name leiyu # 如果name的值不存在,那么就设置其为leiyu
"0"    # 返回值是0代表的是没有设置成功,返回值是1代表的是设置成功了
local:0>get name 
"leiyujia"

批量操作

  • 注意msetnx是一个原子性操作,要么一起成功,要么一起失败
local:0>mset k1 v1 k2 v2 k3 v3  # 批量操作设置
"OK"
local:0>keys *
1)  "k1"
2)  "k2"
3)  "k3"
 
 local:0>msetnx k1 o1 k2 o2 k3 o3 # 不存在的时候再设置
 "0"    # 返回值是0,设置失败,说明存在
 local:0>keys *
 1)  "k1"
 2)  "k2"
 3)  "k3"
 local:0>get k1
 "v1"

设置对象的值

  • 设置一个user:1的对象 值为json字符串来保存一个对象
local:0>set user:1 {
     name:leiyu,age:18}
"OK"
local:0>get user:1
"{name:leiyu,age:18}"

# 进阶操作来实现对象的保存
local:0>mset user:1:name leiyujia user:1:age 19
"OK"
local:0>mget user:1:name user:1:age
1)  "leiyujia"
2)  "19"

组合命令

  • 先get再set
local:0>getset key1 xiaobai # 如果不存在值,则返回null
null
local:0>get key1
"xiaobai"
local:0>getset key1 leiyu # 如果存在值,则返回原来的值,并设置新的值
"xiaobai"
local:0>get key1
"leiyu"

这里可以类比一下再Java JUC 中的CAS理论,比较并交换,比较之后再替换,如果一样其实替换之后的结果还是原来的结果,如果比较之后不一样就会替换为新的值。

String的使用场景

  • value除了可以存储字符串之外还可以用来存储数字

  • 比如说实现计数器(阅读量的统计可能会使用到)

  • 统计多单位的数量(比如CSDN博客每一个人都有自己的id,但是每个id有自己独特的属性值:粉丝数,收藏数,点赞数,要对于该用户的这些数据进行统计的话,就可以用到String)

  • 对象缓存存储

List(列表)

在Redis的list类型和Java中的list类型很像,但是在Redis中,我们可以将List玩成栈、队列、阻塞队列等数据结构。

  • 在list中添加值(左插/右插)
  • 在list中获取值
local:0>lpush name leiyu # 在list(name)中添加值leiyu(从左边插入)
"1"
local:0>lpush name xiaobai
"2"
local:0>lpush name dabaitou
"3"
local:0>lrange name 0 -1  # 获取list中的所有值(使用的是步长的方式)
 1)  "dabaitou"
 2)  "xiaobai"
 3)  "leiyu"
local:0>lrange name 0 1  # 注意在;list中获取值是从后往前获取的,也就是说你添加的越晚,他的下标越小
 1)  "dabaitou"
 2)  "xiaobai"
 
 local:0>rpush name tudou #在列表的右边插入(也就是在尾部插入一个值)
"4"
local:0>lrange name 0 -1 # 你发现tudou值放在了列表的尾部
 1)  "dabaitou"
 2)  "xiaobai"
 3)  "leiyu"
 4)  "tudou"
  • 移除一个元素
local:0>lrange name 0 -1
1)  "dabaitou"
2)  "xiaobai"
3)  "leiyu"
4)  "tudou"
local:0>lpop name  # 将最左边的值移除,也就是将dabaitu移除
"dabaitou"
local:0>lrange name 0 -1
1)  "xiaobai"
2)  "leiyu"
3)  "tudou"
local:0>rpop name # 将list中最右边的值移除,也就是移除了tudou的值 
"tudou"
local:0>lrange name 0 -1
1)  "xiaobai"
2)  "leiyu"
  • 获取某一个key的某值
    • 其实也就是将list当做一个数组来实现,可以获取到具体位置的值。
    • 注意index来获取值的时候,是从左边开始获取值的,也就是左边的位置是index计算开始位置的。
local:0>lrange name 0 -1 
 1)  "xiaobai"
 2)  "leiyu"
local:0>lindex name 0 # 通过下标获取具体的值
"xiaobai"
  • 获取list的长度(或者有多少个元素)
local:0>flushdb # 清空了当前数据库
"OK"
local:0>keys *

local:0>lpush name n1 #添加可n1 ,n2 ,n3三个值
"1"
local:0>lpush name n2
"2"
local:0>lpush name n3
"3"
local:0>llen name #获取当前列表的长度
"3"  # 返回了当前列表的长度
  • 移除指定的值
    • 因为lits中的值是允许重复的,因此在移除的时候,设置的移除的数目可以不为1
    • 并且如果设置的要移除的数目是大于其原本数目的,那么就相当于移除了所有的该元素,不会报错
local:0>lrem name 1 n1  # 1代表的是要移除的数目,因为在list中的值是允许重复的
"1"
local:0>lrange name 0 -1  # 移除之后查看
 1)  "n3"
 2)  "n2"
  • 截断操作
    • 截断该list 只截取位置1到位置2的元素 [start,end]
local:0>rpush name hello
"1"
local:0>rpush name hello1
"2"
local:0>rpush name hello2
"3"
local:0>rpush name hello3
"4"
local:0>ltrim name 1 2  #截断该list   只截取位置1到位置2的元素 [start,end]
"OK"
local:0>lrange name 0   -1
1)  "hello1"
2)  "hello2"
  • 命令:rpoplpush:将第一个list的最右边的元素去除并添加到第二个list中的左边
    • rpoplpush list1 list2 : 该命令后面是两个list 第一个list表示要移除最后一个元素的list,第二个list表示要将该元素添加到最后的元素
    • 操作之后第一个list中的最后一个值就被移除了,而第二个list中会在左边添加一个新的值
local:0>rpush name hello1
"1"
local:0>rpush name hello2
"2"
local:0>rpush name hello3
"3"
local:0>rpoplpush name name1 # 移除name中的最后一个值并将其添加到name1列表中
"hello3"
local:0>keys * # 查看数据库中的所有key
 1)  "name1"
 2)  "name"
local:0>lrange name1 0 -1  # 获取name1列表的值,发现的确添加了新的元素就是我们移除的元素
 1)  "hello3"
  • lset:将list中指定下标的值替换为另一个值
    • 注意该方式添加元素的额方式必须要求该list是存在的
local:0>lset list 1 leiyu # 尝试添加list集合的下标为1的位置的元素是leiyu
"ERR no such key" # 输出没有这个key,也就是这个key不存在
local:0>lpush list leiyu  # 先将该key随便添加一个值
"1"
local:0>lset list 0 leiyu2  # 然后用了lset命令来修改其的值
"OK"          # 修改成功
local:0>lrange list 0 -1  # 查看一下现在list中的value,发现是ok的
1)  "leiyu2"
  • LINSERT:可以在指定的值的前面/后面插入指定的值
local:0>rpush name leiyu
"1"
local:0>rpush name leiyu1
"2"
local:0>rpush name leiyu2
"3"
local:0>rpush name leiyu3
"4"
local:0>linsert name after leiyu3 leiyu4 # 在name列表的leiyu3元素的后面插入leiyu4
"5"
local:0>lrange name 0 -1
1)  "leiyu"
2)  "leiyu1"
3)  "leiyu2"
4)  "leiyu3"
5)  "leiyu4"

List小结

  • 可以将List当成一个链表,可以在其前面和后面插入(也就是其是一个双端的列表)
  • 如果key不存在,创建新的列表
  • 如果key存在,新增内容
  • 如果移除了所有的值,空链表也代表不存在
  • 在两边插入或者改动值,效率最高!中间元素,相对效率比较低

在实际使用中,List可以被用做栈(用一端来控制输入输出,先进后出),队列(两端输入和输出,一端只接受,一端只输出,先进先出的实现).

Set(集合)

代表的是无序的不重复的集合。

集合数据类型和Java中的集合数据类型相似都是不能有重复的值

  • sadd:添加元素
  • smembers:查看set中的所有元素
  • sismemer 集合名 集合元素:判断一个元素是否是该集合中存在
local:0>sadd name leiyu  # 集合中添加值
"1"
local:0>sadd name leiyu  # 集合中不能添加想听的值
"0"  # 返回值是0 ,说明在添加重复元素的时候失败,不能添加重复的元素值
local:0>sadd name ""  # 集合中可以添加空的值
"1"
local:0>smembers name  # 查看集合中的所有值
1)  "leiyu"
2)  ""
local:0>sismember name leiyu # 查看集合中是否存在某一个具体的值
"1"
  • scrd 集合名 :输出该集合中的元素个数
local:0>scard name
"2"
  • srem 集合 元素值:移除掉集合中某一个具体的元素值
local:0>srem name ""  #移除name集合中""的值
"1"
local:0>smembers name  # 查看当前数据库中name集合的所有值
 1)  "leiyu"
  • srandmember 集合名:随机取集合中的一个元素
  • srandmember 集合名 取出元素的个数:随机取集合中n个元素的个数(n就是定义的取出的个数)
local:0>sadd name leiyu
"1"
local:0>sadd name leiyu1
"1"
local:0>sadd name leiyu2
"1"
local:0>sadd name leiyu3
"1"
local:0>sadd name leiyu4
"1"
local:0>srandmember name  # 随机取集合中的一个元素  取出的元素是leiyu3
"leiyu3"
local:0>srandmember name #  随机取集合中的一个元素  取出的元素是leiyu2
"leiyu2"
local:0>srandmember name 2
 1)  "leiyu"
 2)  "leiyu1"
local:0>srandmember name 2
 1)  "leiyu"

  • spop:随机移除元素
local:0>smembers name
1)  "leiyu3"
2)  "leiyu"
3)  "leiyu4"
4)  "leiyu1"
5)  "leiyu2"
local:0>spop name
"leiyu4"
local:0>smembers name
1)  "leiyu"
2)  "leiyu1"
3)  "leiyu3"
4)  "leiyu2"
  • 将一个指定的值移到另外一个集合中
local:0>sadd set leiyu
"1"
local:0>sadd set leiyu1
"1"
local:0>sadd set leiyu2
"1"
local:0>sadd set leiyu3
"1"
local:0>sadd set leiyu4
"1"
local:0>sadd set2 xiaobai
"1"
local:0>sadd set set2 leiyu #注意是支持批量添加的
"1"
local:0>smembers set2
1)  "xiaobai"
local:0>smembers set
1)  "leiyu3"
2)  "leiyu"
3)  "leiyu4"
4)  "leiyu1"
5)  "leiyu2"
6)  "set2"
local:0>smove set set2 leiyu # 将leiyu从set中移除并添加到set2中
"1"
local:0>smembers set2 # 查看set2中所有的元素
1)  "leiyu"
2)  "xiaobai"
  • 集合来实现交集、并集、补集

使用场景:比如在微博中有显示你和朋友的共同关注,或者根据好友关注列表推荐给你关注的列表(这些人是好友关注了的,是你没关注的)

  • sdiff 集合1 集合2..输出集合1和集合2(…)等的不同的元素差集
  • sinter 集合1 集合2..输出集合1和集合2(…)等的相同的元素交集
  • sunion 集合1 集合2..输出集合1和集合2(…)等的并集
local:0>sadd name1 leiyu
"1"
local:0>sadd name1 xiaobai
"1"
local:0>sadd name2 tudou
"1"
local:0>sadd name2 leiyu
"1"
local:0>sadd name1 dugua
"1"
local:0>sdiff name1 name2
 1)  "xiaobai"
 2)  "dugua"
local:0>sinter name1 name2
 1)  "leiyu"
local:0>sunion name1 name2
 1)  "leiyu"
 2)  "xiaobai"
 3)  "tudou"
 4)  "dugua"

Hash(哈希)

  • 可以被当做一个map集合 key - map!这时候这个值是一个map集合

  • hset:在hash中存一个元素值

  • hget在hash中取一个元素值

local:0>hset name1 field leiyu # field代表的是该name集合的一个字段
"1"
local:0>hget name1 field  # 去field字段的所有值
"leiyu"
  • hmset:支持一次写入多个字段和多个值
  • hmget:支持一次读取多个字段和多个值
local:0>hmset name field1 leiyu field2 xiaobai
"OK"
local:0>hmget name field1 field2
 1)  "leiyu"
 2)  "xiaobai"
  • hgetall:获取hash中的所有字段和所以值
local:0>hgetall name
 1)  "field1"
 2)  "leiyu"
 3)  "field2"
 4)  "xiaobai"
  • hdel删除hash指定的key字段
local:0>hdel name field1 #删除hash指定的key字段,删除key之后,对应的value也会消失
"1"
local:0>hgetall name
 1)  "field2"
 2)  "xiaobai"
  • hlen:获取当前hash的有多少个hash字段
local:0>hlen name
"1"
  • hexists:判断hash的某一个字段是否存在
local:0>hexists name field2 #判断name的field2字段是否存在
"1"     #返回值是1代表存在  返回值是0代表不存在
  • hkeys:获取hash的所有的key字段
  • hvals:获取hash的所有的value值
local:0>hkeys name
 1)  "field2"
local:0>hvals name
 1)  "xiaobai"
  • hincrby:让hash的某个字段的值自增某一个指定的值
  • hdecrby:让hash的某个字段的值自减某一个指定的值
local:0>hmset name field1 leiyu field2 5
"OK"
local:0>hincrby name field2 3
"8"
  • hsetnx:不存在时才操作
local:0>hsetnx name field3 tudou
"1"
local:0>hkeys name 
 1)  "field1"
 2)  "field2"
 3)  "field3"
local:0>hvals name
 1)  "leiyu"
 2)  "8"
 3)  "tudou"

使用场景

hash可以用作用户信息的保存。

比如说用户有id name age等属性

local:0>hmset user:1 name 1 age 18
"OK"
local:0>hgetall user:1
 1)  "name"
 2)  "1"
 3)  "age"
 4)  "18"

hash因为有字段的原因,更加适合存储对象,而String类型更加适合字符串存储。

如果使用字符串储存的对比

local:0>hmset user:1 name:leiyu age:18
"OK"
local:0>hgetall user:1
 1)  "name:leiyu"
 2)  "age:18"

Zset(有序集合)

和Set一样,Zset比较特殊的一点是其是可以排序的,ZSet有一个值来代表其的优先程度,用于排序。

  • 添加元素和获取元素的操作
local:0>zadd salary 500 xiaobai #添加元素
"1"
local:0>zadd salary 2500 leiyu
"1"
local:0>zrange salary 0 -1 #获取元素
 1)  "xiaobai"
 2)  "leiyu"
  • Zrangebyscore:输出排序之后的元素(默认的方式是从小到大)
local:0>zrangebYscore salary -inf +inf  # -inf代表的是负无穷 +inf代表的是正无穷
 1)  "xiaobai"
 2)  "leiyu"
 local:0>zrangebYscore salary -inf +inf withscores
 1)  "xiaobai"
 2)  "500"
 3)  "leiyu"
 4)  "2500"

如果不想采用从小到大的顺序排序,那么就要使用zrevrange

  • zrevrange:采用从大到小的顺序排序
local:0>zrevrange salary 0 -1
 1)  "leiyu"
 2)  "xiaobai"
  • zcard:获取有序集合中的个数
local:0>zcard salary
"2"
  • zcount:统计在区间范围内的值的个数
local:0>zcount salary 0 +inf
"2"

使用场景

比如说班级成绩排序,或者工资表排序等。

或者也可以作为一个等级划分,比如说普通消息的等级为1,重要消息的等级为2,紧急消息的等级是3。

或者排行榜等等也是可以使用到的。Top100。

你可能感兴趣的:(Redis,列表,数据库,字符串,redis)