Redis学习笔记----存储结构

众所周知,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 name zhangsan

查询字符串 get name

1.2 批量字符串写入和查询

批量写入字符串 mset name1 zhangsan name2 lisi

批量查询字符串  mget name1 name2

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

1.3 删除

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

1.4 设置过期时间

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

expire name 5(name5秒后过期,在这期间访问name可以,过期之后就拿不到name的值了)

 ②setex name 5 zhangsan(等价于 expire+set,设值的时候加过期时间)

1.5 setnx

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

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

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

setnx还经常用于分布式锁

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

1.6 数值计算

自增:incr age

加上定值: incrby age  5

加上浮点值:incrbyfloat by  2.5

自减:decr age

减去定值:decr age 5

 * value的最大值是Long的最大值,超过会报错

1.7 字符串拼接

append name san 

 

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  names  zhangsan lisi wangwu

左边取数据:lpop names

这个就实现了队列的功能

2.2 栈(右进右出)

右边存数据: rpush  names  zhangsan lisi wangwu

右边取数据:rpop names

2.3 查看元素

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

查询列表第一个元素:lindex list1 0

查询列表第二个元素:lindex list1 1

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

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

查询列表所有元素:lrange list1 0 -1

 查询列表长度:llen list1

2.4 获取元素

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

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

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

brpoplpush list1 list2 5

 

2.5 插入元素

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

 

 当然,也可以在bbb后插入333:linsert list after bbb 333

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

2.6 移除元素

移除列表中的2个a:lrem list 2 a 

 只保留原列表中的2-5区间的元素:ltrim list 2 5

3.Hash

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

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

3.1 设值

给users设值:hset users name zhangsan age 18

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

3.2 获取值

获取user的name:hget user name

获取user的name和age:hmget user name age

获取user中所有属性:hkeys user

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

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

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

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

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 user age 1

给age加2.5:hincrbyfloat user age 2.5

test:0>hincrby user age 1
"19"

test:0>hincrbyfloat user age 2.5
"21.5"

test:0>

3.4 删除

删除user中的name和age:hdel user name age

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  5

主要参考:Redis 字符串(String) | 菜鸟教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值