众所周知,Redis有五种存储结构,String,List,Set,Zset,Hash

目录

1. String

1.1 单个字符写入和查询

1.2 批量字符串写入和查询

1.3 删除

1.4 设置过期时间

1.5 setnx

1.6 数值计算

1.7 字符串拼接

1.8 bitmap

2. list

2.1 队列(右进左出)

2.2 栈(右进右出)

2.3 查看元素

2.4 获取元素

2.5 插入元素

2.6 移除元素

3.Hash

3.1 设值

3.2 获取值

 3.3 值计算

3.4 删除

4. set

4.1 基本操作

4.2 集合操作

5.zset(sorted set)

6. 其他


1. String

Redis 的字符串是动态字符串,是可以修改的字符串,内部结构实现上类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配,如图中所示,内部为当前字符串实际分配的空间 capacity 一般要高于实际字符串长度 len。当字符串长度小于 1M 时,扩容都是加倍现有的空间,如果超过 1M,扩容时一次只会多扩 1M 的空间。需要注意的是字符串最大长度为 512M。

1.1 单个字符写入和查询

写入字符串 set

查询字符串 get

redission compareAndSet 过期时间_数据库

1.2 批量字符串写入和查询

批量写入字符串 mset

批量查询字符串  mget

redission compareAndSet 过期时间_数据_02

 批量对多个字符串进行读写,可以节省网络耗时开销

1.3 删除

删除的话,只支持单个删除

redission compareAndSet 过期时间_数据库_03

1.4 设置过期时间

给key设置过期时间,单位是秒:

① expire

redission compareAndSet 过期时间_数据库_04

setex

redission compareAndSet 过期时间_学习_05

1.5 setnx

setnx命令(set if not exists):当不存在的时候设值

redission compareAndSet 过期时间_字符串_06

(给name设值zhangsan,然后用setnx给name设值lisi,因为name这个key存在,setnx的设值不起作用,拿到的name值还是zhangsan)  

redission compareAndSet 过期时间_数据库_07

(先删除name值,然后setnx name,此时因为name这个key不存在了,所以setnx设值成功)

setnx还经常用于分布式锁

上次我还用setnx实现防重复提交(如果setnx(key)== 1,则这条记录已经保存过了,不再处理)

1.6 数值计算

自增:incr

加上定值: incrby

加上浮点值:incrbyfloat

redission compareAndSet 过期时间_redis_08

自减:decr

减去定值:decr

redission compareAndSet 过期时间_数据_09

*

1.7 字符串拼接

append

 

redission compareAndSet 过期时间_数据_10

1.8 bitmap

redis的还有一个很重要的作用就是实现了bitmap

数据存储在bitmap中,如果在bitmap中可以查到,那么这条数据可能存在;如果bitmap中不存在,那么这条数据一定不存在。在访问数据库之前提前判断,减轻数据库的访问压力。

2. list

Redis 的列表相当于 Java 语言里面的 LinkedList,注意它是链表而不是数组。这意味着 list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为 O(n)。

一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

list主要有两个操作push(存数据)、pop(取数据),然后又有两个方向,左边和右边

list经常用来做消息队列

2.1 队列(右进左出)

右边存数据:rpush

左边取数据:lpop

redission compareAndSet 过期时间_字符串_11

这个就实现了队列的功能

2.2 栈(右进右出)

右边存数据: rpush

右边取数据:rpop

redission compareAndSet 过期时间_字符串_12

2.3 查看元素

之前都是直接取出来元素,现在是查看元素,不取出来

查询列表第一个元素:lindex

查询列表第二个元素:lindex

查询列表最后一个元素:lindex

查询列表1-3个元素:lrange

查询列表所有元素:lrange

redission compareAndSet 过期时间_数据库_13

llen

redission compareAndSet 过期时间_redis_14

2.4 获取元素

从list1中取第一条数据,如果取不到数据,等待5秒:blpop

从list2中取最后一条数据,如果取不到数据,等待5秒:brpop

redission compareAndSet 过期时间_字符串_15

将list1中的最后一条数据插入到list2中的第一条并返回该数据,如果list1中没有数据,等待5秒后返回:

brpoplpush

 

redission compareAndSet 过期时间_数据_16

redission compareAndSet 过期时间_字符串_17

redission compareAndSet 过期时间_字符串_18

2.5 插入元素

在列表中的bbb前插入ddd:linsert list before

 

redission compareAndSet 过期时间_数据_19

linsert list after

在第二个值的地方插入222:lset

redission compareAndSet 过期时间_学习_20

2.6 移除元素

移除列表中的2个a:lrem

redission compareAndSet 过期时间_数据_21

ltrim

redission compareAndSet 过期时间_字符串_22

3.Hash

哈希是redis除了string类型外,用的最多的类型了

Redis 中每个 hash 可以存储 2^32 - 1 键值对(40多亿)

3.1 设值

给users设值:hset

当gender没有值时,给gender赋值:hsetnx

redission compareAndSet 过期时间_redis_23

3.2 获取值

获取user的name:hget

获取user的name和age:hmget

获取user中所有属性:hkeys

获取user中所有属性的数量:hlen

获取user中所有的属性值:hvals

获取user中所有的键值对:hgetall

查看user中是否有属性xxx:hexists

test:0>hset user name zhangsan age 18 gender M
"0"

test:0>hget user name
"zhangsan"

test:0>hmget user name age
 1)  "zhangsan"
 2)  "18"
test:0>hkeys user
 1)  "name"
 2)  "age"
 3)  "gender"
test:0>hlen user
"3"

test:0>hvals user
 1)  "zhangsan"
 2)  "18"
 3)  "M"
test:0>hgetall user
 1)  "name"
 2)  "zhangsan"
 3)  "age"
 4)  "18"
 5)  "gender"
 6)  "M"
test:0>

 3.3 值计算

给age加1:hincrby

给age加2.5:hincrbyfloat

test:0>hincrby user age 1
"19"

test:0>hincrbyfloat user age 2.5
"21.5"

test:0>

3.4 删除

删除user中的name和age:hdel

test:0>hdel user name age
"2"

test:0>hkeys user
 1)  "gender"
test:0>

4. set

set相当于java中的HashSet,无序

4.1 基本操作

test:0>sadd set1 a b c a d f b #给set1中添加元素,因为set中的值不重复,所以只添加了5个
"5"

test:0>scard set1 # 获取set1中元素的数量,可以用来存放点赞的人,然后获取点赞量
"5"

test:0>sismember set1 a # 判断set1中是否包含元素a
"1"

test:0>sismember set1 g # 判断set1中是否包含元素g
"0"

test:0>spop set1 # 随机弹出一个元素并返回
"f"

test:0>srandmember set1 2 # 在set1中随时拿出2个元素,经常用于抽奖
 1)  "d"
 2)  "a"
test:0>srem set1 b c # 移除set1中的元素b和c,可以只移除一个或多个
"2"

4.2 集合操作

test:0>sadd set1 a b c d e
"5"

test:0>sadd set2 d e f g
"4"

test:0>sdiff set1 set2 # 返回set1与set2的差异
 1)  "c"
 2)  "b"
 3)  "a"
test:0>sdiff set2 set1 # 返回set2与set1的差异
 1)  "f"
 2)  "g"
test:0>sunion set1 set2 # 返回set1和set2中所有的元素
 1)  "f"
 2)  "g"
 3)  "d"
 4)  "e"
 5)  "c"
 6)  "b"
 7)  "a"
test:0>sunionstore set3 set1 set2 # 返回set1和set2中所有的元素并存入set3
"7"

test:0>smembers set3 # 查询set3中所有元素
 1)  "f"
 2)  "g"
 3)  "d"
 4)  "e"
 5)  "c"
 6)  "b"
 7)  "a"
test:0>sinter set1 set2 # 返回set1和set2中元素的并集
 1)  "e"
 2)  "d"
test:0>sinterstore set4 set1 set2 # 返回set1和set2中元素的并集并存入set4
"2"

test:0>smembers set4 # 查询set4中所有元素
 1)  "e"
 2)  "d"
test:0>

5.zset(sorted set)

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为

2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。

test:0>zadd chengji 60 zhangsan 60 lisi 70 wangwu 80 zhaoliu 90 mazi # 往chengji中添加值
"5"

test:0>zrangebylex chengji - + # 根据字典序返回有序集合的成员,-表示最小,+表示最大
 1)  "lisi"
 2)  "zhangsan"
 3)  "wangwu"
 4)  "zhaoliu"
 5)  "mazi"

test:0>zrangebyscore chengji 0 100 # 返回score在0-100之间的有序集合
 1)  "lisi"
 2)  "zhangsan"
 3)  "wangwu"
 4)  "zhaoliu"
 5)  "mazi"
test:0>zrangebyscore chengji 0 100 withscores # 返回score在0-100之间的有序集合及分数
 1)  "lisi"
 2)  "60"
 3)  "zhangsan"
 4)  "60"
 5)  "wangwu"
 6)  "70"
 7)  "zhaoliu"
 8)  "80"
 9)  "mazi"
 10)  "90"
test:0>zrank chengji zhangsan # 返回zhangsan的排名、索引
"1"

test:0>zcard chengji # 获取chengji中的成员数
"5"

test:0>zcount chengji 70 90 # 计算score在70-90之间的成员数(包含)
"3"

test:0>zrangebyscore chengji 70 90 withscores # 返回score在70-90之间的成员及分数
 1)  "wangwu"
 2)  "70"
 3)  "zhaoliu"
 4)  "80"
 5)  "mazi"
 6)  "90"
test:0>zincrby chengji 10 zhangsan # 给zhangsan的score+10
"70"

test:0>zscore chengji zhangsan # 返回zhangsan的score
"70"

# 计算在字典序lisi和zhangsan间的成员数,[表示包含,(表示不包含
test:0>zlexcount chengji [lisi [zhangsan 
"3"

test:0>zrangebylex chengji [lisi [zhangsan # 查看在字典序lisi和zhangsan间的成员
 1)  "lisi"
 2)  "wangwu"
 3)  "zhangsan"

# 计算在字典序lisi和zhangsan间的成员数,(表示不包含zhangsan
test:0>zlexcount chengji [lisi (zhangsan
"2"

test:0>zrangebylex chengji [lisi (zhangsan # 查看在字典序lisi和zhangsan间的成员
 1)  "lisi"
 2)  "wangwu"

test:0>zrank chengji zhangsan # 查看zhangsan的排名
"2"

test:0>zrange chengji 0 5 withscores # 查看第0-5条成员及score
 1)  "lisi"
 2)  "60"
 3)  "wangwu"
 4)  "70"
 5)  "zhangsan"
 6)  "70"
 7)  "zhaoliu"
 8)  "80"
 9)  "mazi"
 10)  "90"
test:0>zrem chengji zhangsan lisi # 移除zhangsan和lisi
"2"

test:0>zrange chengji 0 5 withscores # 查看第0-5条成员及score,已经没有zhangsan和lisi了
 1)  "wangwu"
 2)  "70"
 3)  "zhaoliu"
 4)  "80"
 5)  "mazi"
 6)  "90"
test:0>zremrangebyrank chengji 0 1 # 移除排名0-1的成员(也就是wangwu和zhaoliu)
"2"

test:0>zrange chengji 0 5 withscores # 查看第0-5条成员及score,已经没有wangwu和zhaoliu
 1)  "mazi"
 2)  "90"
test:0>zadd chengji 20 zhangsan 30 lisi 50 wangwu # 添加zhangsan、lisi、wangwu
"3"

test:0>zrange chengji 0 5 withscores # 查看第0-5条成员及score
 1)  "zhangsan"
 2)  "20"
 3)  "lisi"
 4)  "30"
 5)  "wangwu"
 6)  "50"
 7)  "mazi"
 8)  "90"
test:0>zremrangebyscore chengji 0 10 # 移除score在0-10之间的成员
"0"

test:0>zremrangebyscore chengji 0 20 # 移除score在0-20之间的成员
"1"

test:0>zrange chengji 0 5 withscores # 查看第0-5条成员及score
 1)  "lisi"
 2)  "30"
 3)  "wangwu"
 4)  "50"
 5)  "mazi"
 6)  "90"
test:0>zrevrange chengji 0 5 withscores # 倒序查看第0-5条成员及score
 1)  "mazi"
 2)  "90"
 3)  "wangwu"
 4)  "50"
 5)  "lisi"
 6)  "30"

test:0>zrevrangebyscore chengji 100 50 withscores # 倒序查看score在100-50之间的成员及score
 1)  "mazi"
 2)  "90"
 3)  "wangwu"
 4)  "50"
test:0>zrevrangebyscore chengji 100 0 withscores # 倒序查看score在100-0之间的成员及score
 1)  "mazi"
 2)  "90"
 3)  "wangwu"
 4)  "50"
 5)  "lisi"
 6)  "30"
test:0>zrevrank chengji mazi # 倒序查看mazi的排名
"0"

test:0>zrevrank chengji lisi # 倒序查看lisi的排名
"2"

test:0>

综上总结:

lex用来查看字典序

rev用来倒序

6. 其他

redis默认有16个数据库0-15,默认打开会操作第一个数据库,选择第五个的数据库:select