Redis五大数据类型

131 阅读7分钟

三、五大数据类型

1、官方文档

1678089305349.png 翻译

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication)LUA脚本(Lua scripting), LRU驱动事件(LRU eviction)事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

2、Redis-Key

exists key #判断key是存在
move key db #移除key db是代表哪一个库(1-16)
expire key time #设置key的过期时间 time以秒为单位的过期时间
ttl key #查看key还剩余多少过期时间
type key #查看key是什么类型

Redis中文官网 (redis.cn)

Redis命令中心(Redis commands) -- Redis中国用户组(CRUG)

3、String(字符串)

127.0.0.1:6379> set key1 v1 #设置key
OK
127.0.0.1:6379> get key1 #获得值
"v1"
127.0.0.1:6379> exists key1 #判断key是否存在
(integer) 1
127.0.0.1:6379> append key1 "hello" #追加字符串,如果key不存在,就相当于set key
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> strlen key1 #获取key的长度
(integer) 7
127.0.0.1:6379> append key1 ",yang"
(integer) 12
127.0.0.1:6379> get key1
"v1hello,yang"
127.0.0.1:6379> 

127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views #自增1
(integer) 1
127.0.0.1:6379> get views
"1"
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views
(integer) 1
127.0.0.1:6379> get views
"1"
127.0.0.1:6379> decr views #自减1
(integer) 0
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incrby views 10 #指定自增步长
(integer) 10
127.0.0.1:6379> get views
"10"
127.0.0.1:6379> decrby views 5#指定自减步长
(integer) 5
127.0.0.1:6379> get views
"5"

27.0.0.1:6379> get key1
"yanghang"
127.0.0.1:6379> getrange key1 0 3 #截取字符串[0,3]
"yang"
127.0.0.1:6379> getrange key1 0 -1 #获取全部的字符串和get key一样
"yanghang"
127.0.0.1:6379> 

127.0.0.1:6379> set key2 asdffggg
 OK
127.0.0.1:6379> setrange key2 1 11 #替换指定位置开始的字符串 sd->11
(integer) 8
127.0.0.1:6379> get key2
"a11ffggg"

setex(set with expire) #设置过期时间
setnx(set if not exist) #如果这个key不存在就设置
127.0.0.1:6379> setex key3 30 yang
OK
127.0.0.1:6379> ttl key3
(integer) 26
127.0.0.1:6379> get key3
(nil)
127.0.0.1:6379> setnx mykey mogodb
(integer) 1
127.0.0.1:6379> setnx mykey mogodb
(integer) 0
127.0.0.1:6379> 
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #设置多个值
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k3"
3) "k2"
127.0.0.1:6379> mget k1 k2 k3 #获取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4 #原子性操作,要么全部成功,要么全部失败
(integer) 0
127.0.0.1:6379> keys *
1) "k1"
2) "k3"
3) "k2"

存储对象

127.0.0.1:6379> mset user:1:name zhangsan user:1:age 12
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "12"

先get再set

127.0.0.1:6379> getset n1 redis
(nil)
127.0.0.1:6379> getset n1 m1 #如果存在值,获取原来的值,并设置新的值
"redis"
127.0.0.1:6379> get n1
"m1"
127.0.0.1:6379> 

4、List

基本的数据类型,列表。在Redis里面,可以将List看成队列,栈,阻塞队列。所有命令都是以l开头。

1678170327108.png

127.0.0.1:6379> lpush list one #将一个值放在链表的头部
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1 #从左边开始获取具体的值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1 #从左边开始获取具体的值[0,1]
1) "three"
2) "two"
127.0.0.1:6379> rpush list right #从右边开始获取具体的值
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> rpop list #从list右边弹出第一个
"right"
127.0.0.1:6379> lpop list #从list左边弹出第一个
"three"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lindex list 1 #通过下标获得list中的某一个值
"one"
127.0.0.1:6379> llen list #返回列表的长度
(integer) 2
127.0.0.1:6379> lrem list 1 one #移除list集合中指定个数value,精确指定
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> lrem list 2 three
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "two"
127.0.0.1:6379> rpush mylist hello
(integer) 1
127.0.0.1:6379> rpush mylist hello1 hello2 hello3
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "hello1"
3) "hello2"
4) "hello3"
127.0.0.1:6379> ltrim mylist 1 2 #通过下标截取指定长度,这个list已经被改变了,截取了只剩下截取的元素
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "hello1"
2) "hello2"
##################################################
rpoplpush #移除列表的最后一个元素,将他移动到一个新的列表中
127.0.0.1:6379> rpush mylist hello hello1 hello2
(integer) 3
127.0.0.1:6379> rpoplpush mylist myotherlist
"hello2"
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "hello1"
127.0.0.1:6379> lrange myotherlist 0 -1
1) "hello2"

##################################
lset #将列表中指定下标的值替换为另外的一个值,更新操作
127.0.0.1:6379> exists list
(integer) 0
127.0.0.1:6379> lset list 0 item #如果不存在列表我们去更新就会报错
(error) ERR no such key
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrange list 0 0
1) "value1"
127.0.0.1:6379> lset list 0 item #如果存在就会更新当前下标的值
OK
127.0.0.1:6379> lrange list 0 0
1) "item"
127.0.0.1:6379> lset list 1 other #如果不存在就会报错
(error) ERR index out of range
########################################
linsert #将某个具体的value插入到列的某个元素的前面或者后面
127.0.0.1:6379> rpush mylist hell world
(integer) 2
127.0.0.1:6379> linsert mylist before world other
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "hell"
2) "other"
3) "world"
127.0.0.1:6379> linsert mylist after world new
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "hell"
2) "other"
3) "world"
4) "new"

小结

  • list实际上是一个链表,before Node after,left,right都可以插入值
  • 如果key不存在,创建新的链表
  • 如果key存在,新增内容
  • 如果移除了所有的值,空链表,也代表不存在
  • 在两边插入或者改动值,效率最高!中间元素,相对来说效率会底一点
  • 可以使用list做消息队列

5、Set

set中的值是不能存在的

######################################
127.0.0.1:6379> sadd myset hell yang hang #向集合中添加元素
(integer) 3
127.0.0.1:6379> smembers myset #查看所有元素
1) "hang"
2) "yang"
3) "hell"
127.0.0.1:6379> sismember myset yang #判断某个值是否存在于set集合中
######################################
(integer) 1
127.0.0.1:6379> scard myset #查看set集合中有多少个元素
(integer) 3
27.0.0.1:6379> smembers myset
1) "hang"
2) "yang"
3) "hell"
127.0.0.1:6379> srem myset hell
(integer) 1
127.0.0.1:6379> smembers myset
1) "hang"
2) "yang"
######################################
set 是无序不重复集合,抽随机
127.0.0.1:6379> srandmember myset #随机抽取元素
"yang"
127.0.0.1:6379> srandmember myset
"yang"
127.0.0.1:6379> srandmember myset
"yang"
127.0.0.1:6379> srandmember myset
"hang"
127.0.0.1:6379> srandmember myset
"hang"
127.0.0.1:6379> srandmember myset
"yang"
######################################
删除指定的key,随机删除key
127.0.0.1:6379> smembers myset
1) "hang"
2) "yang"
127.0.0.1:6379> spop myset
"yang"
127.0.0.1:6379> smembers myset
1) "hang"
######################################
将一个指定的值,移动到另外的集合中
127.0.0.1:6379> sadd myset hello world yanghang
(integer) 3
127.0.0.1:6379> smembers myset
1) "hello"
2) "world"
3) "yanghang"
127.0.0.1:6379> sadd myset2 other
(integer) 1
127.0.0.1:6379> smove myset myset2 yanghang
(integer) 1
127.0.0.1:6379> smembers myset2
1) "other"
2) "yanghang"
######################################
微博、B站,共同关注(并集)
数据集合类:
 - 差集
 - 交集
 - 并集
 127.0.0.1:6379> sadd key1 a b c d
(integer) 4
127.0.0.1:6379> sadd key2 c d e f
(integer) 4
127.0.0.1:6379> sdiff key1 key2 #差集
1) "a"
2) "b"
127.0.0.1:6379> sinter key1 key2 #交集
1) "d"
2) "c"
127.0.0.1:6379> sunion key1 key2 #并集
1) "c"
2) "f"
3) "d"
4) "a"
5) "b"
6) "e"

小结

微博,A用户将所有关注的人放在一个set集合中!将它的粉丝也放在一个集合中,共同关注!六度分割理论!

6、Hash(哈希)

Map集合,key-Map集合!这个时候的值是一个map集合!本质上和String类型没有太大区别

set myhash filed yanghang

127.0.0.1:6379> hset myhash field kuangsheng #set一个具体的key-value
(integer) 1
127.0.0.1:6379> hget myhash field
"kuangsheng"
127.0.0.1:6379> hmset myhash field hello field2 world # set多个key-value
OK
127.0.0.1:6379> hmget myhash field #获取多个字段值
1) "hello"
127.0.0.1:6379> hget myhash field2
"world"
127.0.0.1:6379> hgetall myhash #获取全部的数据
1) "field"
2) "hello"
3) "field2"
4) "world"
127.0.0.1:6379> hdel myhash field #删除hash指定的key字段!对应的value值也就消失了
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field2"
2) "world"
######################################
127.0.0.1:6379> hmset myhash field1 hello field2 world
OK
127.0.0.1:6379> hgetall myhash
1) "field2"
2) "world"
3) "field1"
4) "hello"
127.0.0.1:6379> hlen myhash #获取hash的字段数量
(integer) 2
######################################
127.0.0.1:6379> hexists myhash field1 #判断hash指定字段是否存在
(integer) 1
127.0.0.1:6379> hexists myhash field2
(integer) 1
######################################
#只获取field
#只获取value
127.0.0.1:6379> hkeys myhash
1) "field2"
2) "field1"
127.0.0.1:6379> hvals myhash
1) "world"
2) "hello"
(integer) 1
######################################
127.0.0.1:6379> hset myhash field3 5 #指定增量
(integer) 1
127.0.0.1:6379> hincrby myhash field3 2
(integer) 7
127.0.0.1:6379> hincrby myhash field3 -1
(integer) 6
127.0.0.1:6379> hsetnx myhash field4 hello #如果不存在则可以设置
(integer) 1
127.0.0.1:6379> hsetnx myhash field4 world #如果存在则不可以设置
(integer) 0

小结

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

7、Zset(有序集合)

在set的基础上,增加了一个值 set k1 v1 zset k1 score1 v1

127.0.0.1:6379> zadd myset 1 one #添加一个值
(integer) 1
127.0.0.1:6379> zadd myset 2 two 3 three #添加多个值
(integer) 2
127.0.0.1:6379> zrange myset 0 -1
1) "one"
2) "two"
3) "three"
####################################################
#排序如何实现
# zrangebyscore key min max
integer) 1
127.0.0.1:6379> zadd salary 5000 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 200 xiaoyang
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf #显示全部的用户 从小到大
1) "xiaoyang"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> zrevrange salary 0 -1 #从大到小排序
1) "zhangsan"
2) "xiaoyang"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores #显示全部的用户并且附带成绩
1) "xiaoyang"
2) "200"
3) "xiaohong"
4) "2500"
5) "zhangsan"
6) "5000"
127.0.0.1:6379> zrangebyscore salary -inf 2500 withscores #显示工资小于2500员工的升序排列
1) "xiaoyang"
2) "200"
3) "xiaohong"
4) "2500"
####################################################
#移除(rem)元素
27.0.0.1:6379> zrange salary 0 -1
1) "xiaoyang"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> zrem salary xiaohong #移除指定元素
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "xiaoyang"
2) "zhangsan"
####################################################
#获取有序集合中的个数
127.0.0.1:6379> zcard salary
(integer) 2
127.0.0.1:6379> zadd myset 1 hello 2 world 3 yang #获取指定区间元素数量
(integer) 3
127.0.0.1:6379> zcount myset 1 3
(integer) 3