Redis五大数据类型

Redis内部存储的数据为键值对,键的数据类型都是字符串类型,这里说的数据类型是指值的类型。

String(字符串)

使用场景:

  • 存储json类型对象
  • 作为计数器,例如点赞数,粉丝数

追加字符串,如果当前key不存在就相当于新建

1
append name 666

获取字符串长度

1
strlen name

增加减少

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
127.0.0.1:6379> set views 1   
OK
127.0.0.1:6379> incr views # 加1
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views # 减1
(integer) 1
127.0.0.1:6379> get views
"1"
127.0.0.1:6379> incrby views 10 # 设置步长,加10
(integer) 11
127.0.0.1:6379> get views
"11"
127.0.0.1:6379> decrby views 10
(integer) 1
127.0.0.1:6379> get views
"1"

截取字符串

1
2
3
4
5
6
127.0.0.1:6379> get demo
"hello,world"
127.0.0.1:6379> getrange demo 0 4
"hello"
127.0.0.1:6379> getrange demo 0 -1 # 获取全部字符串
"hello,world"

替换

1
2
3
4
127.0.0.1:6379> get demo
"hello,world"
127.0.0.1:6379> setrange demo 6 redis! # 替换指定位置开始的字符串 (integer) 12 127.0.0.1:6379> get demo
"hello,redis!"

设置键值对的时候指定有效期

1
setex key1 10 "hello" # 设置key1的值为hello,10秒后过期

如果key不存在就创建

1
setnx key2 "hello2"

批量设置

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> mset k1 v1 k2 v1 k3 v3     
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"
127.0.0.1:6379> msetnx k1 v1 k4 v4 # 原子操作
(integer) 0
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"

设置对象 user:{id}.{filed}

1
2
3
4
5
127.0.0.1:6379> mset user:1:name zyz user:1:age 21
OK
127.0.0.1:6379> mget user:1:name user:1:age
"zyz"
"21"

先get后set

1
2
3
4
5
6
7
8
127.0.0.1:6379> getset name zyz  # key值不存在,先返回nil,再设置
(nil)
127.0.0.1:6379> get name
"zyz"
127.0.0.1:6379> getset name zyz666 # key存在,返回key值,再设置
"zyz"
127.0.0.1:6379> get name
"zyz666"

List(列表)

是一个双向链表结构,可以用来存储一组数据;从这个列表的前端和后端取数据效率非常高。

使用场景:

  • 模拟队列,堆栈
  • 朋友圈点赞,查询点赞数,点赞人的信息等

插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
127.0.0.1:6379> lpush list 1   # 相当于压栈,操作第一个元素
(integer) 1
127.0.0.1:6379> lpush list 2
(integer) 2
127.0.0.1:6379> lpush list 3
(integer) 3
127.0.0.1:6379> lrange list 0 2
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> rpush list 4 # 相当于从队列的尾部插入 ,操作最后一个元素
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "3"
2) "2"
3) "1"
4) "4"

删除

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> lrange list 0 -1      
1) "3"
2) "2"
3) "1"
4) "4"
127.0.0.1:6379> lpop list # 移除第一个
"3"
127.0.0.1:6379> Rpop list # 移除最后一个
"4"
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "1"

获取值

1
2
127.0.0.1:6379> lindex list 0                           
"2"

查询list长度

1
2
127.0.0.1:6379> llen list   
(integer) 4

根据指定的值删除

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6379> lrange list 0 -1  
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> lrem list 1 4 # 移除value为4的从头开始的第一个值
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "3"
2) "2"
3) "1"

截取元素

1
2
3
4
5
6
7
8
9
127.0.0.1:6379> lrange list 0 -1    
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> ltrim list 0 1 # 通下标[0]截取指定长度[1]
OK
127.0.0.1:6379> lrange list 0 -1
1) "3"
2) "2"

将原列表的最后一个元素移到新的列表中

1
2
3
4
5
6
7
8
9
127.0.0.1:6379> lrange list 0 -1      
1) "3"
2) "2"
127.0.0.1:6379> rpoplpush list list1 # 将list最后一个元素移到list1中
"2"
127.0.0.1:6379> lrange list1 0 -1
1) "2"
127.0.0.1:6379> lrange list 0 -1
1) "3"

更新值,需要先判断list是否存在

1
2
3
4
5
6
127.0.0.1:6379> exists list                                       
(integer) 0
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lset list 0 value2
OK

从指定元素值前面/后面插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
127.0.0.1:6379> lrange list 0 -1  
1) "1"
2) "2"
127.0.0.1:6379> linsert list after 2 3 # 在值为2的元素后面插入一个值为3的元素
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> linsert list before 1 0 # 在值为1的元素前面插入一个值为0的元素
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "0"
2) "1"
3) "2"
4) "3"

List实际上是一个双向链表,前后都可以插入值;key不存在创建新的节点,key存在,新增内容;两边插入或改动效率最高。

消息队列(Lpush,Rpop),栈(Lpush,Lpop)

Set(集合)

值不可重复,值则相同添加失败。

使用场景:

  • 去重
  • 抽奖
  • set运算,交集并集补集差集运算,例如好友推荐

添加值、查看所有值、判断值是否存在

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6379> sadd myset aaa   
(integer) 1
127.0.0.1:6379> sadd myset bbb
(integer) 1
127.0.0.1:6379> smembers myset
1) "bbb"
2) "aaa"
127.0.0.1:6379> sismember myset aaa
(integer) 1
127.0.0.1:6379> sismember myset ccc
(integer) 0

移除指定值的元素

1
2
3
4
5
6
7
127.0.0.1:6379> smembers myset    
1) "bbb"
2) "aaa"
127.0.0.1:6379> srem myset bbb
(integer) 1
127.0.0.1:6379> smembers myset
1) "aaa"

随机挑选元素

1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> smembers myset    
1) "bbb"
2) "aaa"
3) "ccc"
127.0.0.1:6379> srandmember myset
"ccc"
127.0.0.1:6379> srandmember myset
"bbb"
127.0.0.1:6379> srandmember myset
"ccc"

随机删除

1
spop myset

移动指定元素

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6379> smembers myset    
1) "bbb"
2) "aaa"
3) "ccc"
127.0.0.1:6379> smove myset myset2 aaa
(integer) 1
127.0.0.1:6379> smembers myset
1) "bbb"
2) "ccc"
127.0.0.1:6379> smembers myset2
1) "aaa"

差集,交集,并集==>应用场景:B站,微博的共同关注等等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
127.0.0.1:6379> sadd myset a
(integer) 1
127.0.0.1:6379> sadd myset b
(integer) 1
127.0.0.1:6379> sadd myset c
(integer) 1
127.0.0.1:6379> sadd myset2 c
(integer) 1
127.0.0.1:6379> sadd myset2 d
(integer) 1
127.0.0.1:6379> sadd myset2 e
(integer) 1
127.0.0.1:6379> sdiff myset myset2
1) "a"
2) "b"
127.0.0.1:6379> sinter myset myset2
1) "c"
127.0.0.1:6379> sunion myset myset2
1) "d"
2) "c"
3) "b"
4) "a"
5) "e"

Zset(有序集合)

可排序的set,每一个添加值都有一个对应的分数,可通过这个分数进行排序

使用场景:

  • 海量数据的排行,例如天梯排名

添加

1
2
3
4
5
6
7
8
127.0.0.1:6379> zadd myzset 1 value1
(integer) 1
127.0.0.1:6379> zadd myzset 2 value2 3 value3
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1
1) "value1"
2) "value2"
3) "value3"

排序

1
2
3
4
5
6
7
8
127.0.0.1:6379> zrangebyscore myzset -inf +inf # 最小值到最大值排序
1) "value1"
2) "value2"
3) "value3"
127.0.0.1:6379> zrevrange myzset 0 -1 # 从大到小
1) "value3"
2) "value2"
1) "value1"

移除元素

1
zrem myzset value1

获取个数

1
zcard myzset

获取指定区间的成员数量

1
zcount myzset 1 3

Hash(哈希)

可以理解为Map集合,key-map,值是一个Map集合

使用场景:

  • 与String+json相比,存储对象的属性需要频繁修改时,使用Hash,可以针对某个属性单独修改,没有序列化,也不需要修改整个对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
127.0.0.1:6379> hset myhash field1 aaa # 添加一个值
(integer) 1
127.0.0.1:6379> hget myhash field1 # 获取一个指定字段的值
"aaa"
127.0.0.1:6379> hmset myhash field2 bbb field3 ccc # 添加多个键值对
OK
127.0.0.1:6379> hmget myhash field1 field2 # 获取多个字段值
1) "aaa"
2) "bbb"
127.0.0.1:6379> hgetall myhash # 获取全部数据
1) "field1"
2) "aaa"
3) "field2"
4) "bbb"
5) "field3"
6) "ccc"

获取长度

1
hlen myhash

判断字段是否存在

1
2
3
4
127.0.0.1:6379> hexists myhash field1
(integer) 1
127.0.0.1:6379> hexists myhash aaaa
(integer) 0

获取所有字段/值

1
2
3
4
5
6
7
8
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "field2"
3) "field3"
127.0.0.1:6379> hvals myhash
1) "aaa"
2) "bbb"
3) "ccc"

自增,自减

1
2
hincrby myhash field1 1
hincrby myhash field1 -1