2. Redis的数据类型【重点】
1、数据类型介绍
1.1Redis的5种数据类型
redis是一种高级的key-value的存储系统,键是string类型,其中value支持五种数据类型,对于键和值的描述如下所示:
键(key):
【1】键不能重复
【2】作用:标识存储的数据
【3】数据类型:string
【4】命名规则:
1)不能太长:因为查询的效率低,查询起来不方便
2)不能太短:容易重复,同时可读性也差
3)按照规范:HEIMA_STU_LIST
**值(value):**支持5种数据类型
值的数据类型 | 值的格式说明 |
---|---|
string | 字符串类型,类似于Java中String |
hash | 由键值对组成,类似于Java中Map |
list | 列表类型,类似于Java中List,元素是存取有序,可以重复。 |
set | 集合类型,类似于Java中Set,元素是存取无序,不可重复 |
sorted set/zset | 有序的集合类型,每个元素有一个分数用来决定它的顺序。 |
2、string类型的操作命令
目标
学习操作String类型数据的命令
字符串类型string
字符串类型是Redis中最为基础的数据存储类型,它在Redis中以二进制保存。无论存入的是字符串、整数、浮点类型都会以字符串写入。
在Redis中字符串类型的值最多可以容纳的数据长度是512M,这是以后最常用的数据类型。
常用命令
更多命令可以参考Redis中文网:https://www.redis.net.cn
命令 | 功能 |
---|---|
set 键 值 | 添加或修改一个键和值,键不存在就是添加,存在就是修改 |
get 键 | 获取值,如果存在就返回值,不存在返回nil(就是C语言中NULL) |
del 键 | 删除指定的键和值,返回删除的个数 |
SETEX key seconds value | 设置指定key的值,并将 key 的过期时间设为 seconds 秒。此处的value是指key对应的value值。等价于:SET key value ex seconds |
EXPIRE key seconds | 如果一个key已经存在,要设置一个过期时间 |
SETNX key value/set key value nx | 保存键值对,如果key存在则不保存,不存在则保存 |
补充:
批量操作:
mset name lisi addr sh
mget name age addr
del name age
使用场景举例:
- 用户登录后端保存短信验证码,并设置失效时间;
- 代替后端session功能,实现分布式缓存(是将数据分散存储在多台独立的设备上)等;
小结
-
添加值: set 键 值
-
获取值:get 键
-
删除值:del 键
3、hash类型的操作命令
目标
学习hash类型的几个操作命令
概述
Redis中的Hash类型可以看成是键和值都是String类型的Map容器,每一个Hash可以存储4G个键值对。
常用命令
命令 | 功能 |
---|---|
hset 键 字段 值 | 添加键,字段,值 |
hget 键 字段 | 通过键,字段得到值 |
hmset 键 字段 值 字段 值 | multiply多个,一次添加多个字段和值 |
hmget 键 字段 字段 | 通过键,获取多个字段和值 |
hdel 键 字段 字段 | 删除一个或多个字段的值 |
hgetall 键 | 得到这个键下所有的字段和值 |
HKEYS 键 | 获取哈希表中所有字段 |
HVALS 键 | 获取哈希表中所有值 |
Hash数据结构的应用场景:
- 购物车
以用户id为key,商品id为field,商品数量为value,恰好构成了购物车的3个要素,如下图所示
小结
功能 | hash类型的操作命令 |
---|---|
添加值 | hset |
得到值 | hget |
删除值 | hdel |
添加多个字段 | hmset |
得到多个字段值 | hmget |
得到所有字段的值 | hgetall |
场景实现
-
选择合适的数据结构: Redis提供了多种数据结构,对于购物车这种场景,通常使用哈希表(Hash)结构来存储。哈希表允许你以字段-值对的形式存储数据,非常适合购物车中用户ID和商品ID-数量的映射。
-
存储购物车数据: 使用HSET命令来存储购物车数据。假设用户ID是
user123
,商品ID是product456
,数量是2
,你可以使用如下命令:HSET shopping_cart:user123 product456 2
这条命令会创建一个哈希表
shopping_cart:user123
,其中product456
是字段,2
是对应的值。 -
更新购物车数据: 如果用户添加了更多相同商品,你可以使用HINCRBY命令来增加商品数量:
HINCRBY shopping_cart:user123 product456 1
如果用户删除商品或更改数量,你可以使用HSET命令来更新数量。
-
查询购物车数据: 要获取用户的购物车数据,可以使用HGETALL命令:
HGETALL shopping_cart:user123
这将返回用户ID为
user123
的购物车中的所有商品ID和数量。 -
删除购物车数据: 当用户完成购买或清空购物车时,可以使用DEL命令来删除整个哈希表:
DEL shopping_cart:user123
或者,如果只想删除购物车中的某个商品,可以使用HDEL命令:
HDEL shopping_cart:user123 product456
4、list类型的操作命令
目标
学习list类型的操作命令
概述
在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其左部(left)和右部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4G个。
常用命令
命令 | 行为 |
---|---|
lpush 键 元素 元素… | left 从左边向指定的键中添加1个或多个元素,返回列表中元素的个数 |
rpush 键 元素 元素… | right 从右边向指定的键中添加1个或多个元素 |
lpop 键 | 从左边删除一个元素,返回被删除的元素 |
rpop 键 | 从右边删除一个元素,返回被删除的元素 |
lrange 键 开始 结束 | 得到键中指定范围的元素的数据 每个元素都有一个索引号,从左向右0~n 从右向左索引号:-1~-(n+1),每个元素有2个索引号 如果要取出整个列表中所有的元素,索引号应该是:0~-1 |
lindex 键 索引值 | 查询指定索引的元素 |
llen 键 | 获取列表的长度 |
BRPOP key1 [key2 ] timeout | 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止,超时时间单位默认是秒 |
LREM key 删除元素个数 value值 | 从表头删除指定个数的元素 |
使用场景:
- 微信朋友圈点赞,要求按照点赞顺序显示点赞好友信息。如果取消点赞,移除对应好友信息。
- list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中,如京东每日的手机销量排行、学校每次月考学生的成绩排名等,下图是酷狗音乐“K歌擂台赛”的昨日打擂金曲排行榜,每日计算一次,存储在list类型中。
小结
- 从左边添加元素: lpush
- 从右边添加元素:rpush
- 从左边删除元素:lpop
- 从右边删除元素:rpop
- 得到指定范围的元素:lrange
- 得到列表的长度:llen
场景实现
数据存储设计
- 点赞记录: 使用Redis的列表(List)结构来存储点赞记录。列表的头部(左侧)可以用于插入新点赞的用户,这样可以保证列表的顺序是按照点赞时间的逆序排列的。
- 用户信息: 用户信息可以存储在哈希表(Hash)中,其中用户的ID作为键,用户的详细信息作为值。
点赞操作
-
记录点赞: 当用户A给朋友圈动态点赞时,执行以下操作:
-
使用LPUSH命令将用户A的ID插入到该动态的点赞列表的头部:
LPUSH likes:post_id user_id_a
-
likes:post_id
是存储点赞用户的列表,post_id
是朋友圈动态的唯一标识。
-
-
获取点赞列表: 要获取点赞的好友列表,可以使用
LRANGE
命令:LRANGE likes:post_id 0 -1
这将返回点赞列表中的所有用户ID,你可以根据这些ID获取相应的用户信息。
取消点赞操作
-
移除点赞记录: 当用户A取消点赞时,执行以下操作:
-
使用LREM命令从点赞列表中移除用户A的ID:
LREM likes:post_id 0 user_id_a
-
0
表示移除列表中第一次出现的user_id_a
。
-
-
更新点赞列表:
- 如果需要,可以重新排序点赞列表,以确保列表的顺序是最新的。
展示点赞好友信息
- 按顺序展示:
- 通过
LRANGE
获取点赞列表,然后根据列表中的用户ID,查询用户信息哈希表,获取每个用户的详细信息。
- 通过
- 实时更新:
- 当有新的点赞或取消点赞操作时,点赞列表会实时更新,确保展示的点赞顺序是最新的。
性能优化
- 缓存:对于频繁访问的数据,如用户信息,可以使用Redis的缓存机制来提高访问速度。
- 异步处理:点赞和取消点赞的操作可以异步处理,以减少对用户体验的影响。
- 数据一致性:确保点赞和取消点赞的操作在数据库中正确记录,以保持数据的一致性。
安全性考虑
- 权限验证:在执行点赞和取消点赞操作之前,需要验证用户是否有权限对特定的朋友圈动态进行操作。
- 防止滥用:设置点赞频率限制,防止用户频繁点赞或取消点赞。
要实现用户信息的存储和检索,可以使用Redis的哈希表(Hash)数据结构。以下是如何设计和实现哈希表来存储用户信息的步骤:
哈希表设计
-
定义哈希表键名: 为每个用户定义一个唯一的哈希表键名。通常可以使用用户ID作为键名的一部分,例如
user:<user_id>
。 -
存储用户信息: 使用
HMSET
或HSET
命令将用户的各个属性存储在对应的哈希表中。例如,如果用户有属性如用户名、邮箱、头像URL等,可以这样存储:HMSET user:user_id name "用户名" email "user@example.com" avatar_url "http://example.com/avatar.jpg"
其中
user:user_id
是哈希表的键名,name
、email
和avatar_url
是字段,而相应的值分别是用户的用户名、邮箱和头像URL。 -
获取用户信息: 当需要获取某个用户的详细信息时,可以使用
HGETALL
命令:HGETALL user:user_id
这将返回哈希表中所有的字段和值,通常是一个字段-值对的列表。
点赞列表与用户信息的关联
- 从点赞列表获取用户ID: 当获取点赞列表(使用
LRANGE
命令)后,你会得到一系列用户ID。 - 查询用户信息: 遍历这些用户ID,使用
HGETALL
命令为每个用户ID获取其详细信息。 - 构建点赞用户列表: 将获取到的用户信息按照点赞顺序构建成一个列表或数组,然后展示给其他用户。
示例代码
假设你已经通过LRANGE likes:post_id 0 -1
获取了点赞用户的ID列表,以下是如何使用Python和redis-py客户端库来获取并展示这些用户信息的示例代码:
import redis
# 连接到Redis服务器
r = redis.Redis(host='localhost', port=6379, db=0)
# 获取点赞用户的ID列表
likes_list = r.lrange('likes:post_id', 0, -1)
likes_list = list(likes_list) # 转换为Python列表
# 存储用户信息的列表
users_info = []
# 遍历点赞用户的ID列表,获取每个用户的信息
for user_id in likes_list:
user_info = r.hgetall('user:' + user_id) # 获取用户信息
# 将字典的键从bytes转换为字符串
user_info = {k.decode(): v.decode() for k, v in user_info.items()}
users_info.append(user_info)
# 打印用户信息列表
for user in users_info:
print(user)
注意事项
- 确保在存储和检索用户信息时处理好字符编码问题。
- 考虑使用合适的数据结构和序列化格式来存储用户信息,以便于检索和展示。
- 如果用户信息经常变动,确保点赞列表中展示的信息是最新的。
- 根据实际需求,可能需要实现更复杂的用户信息检索逻辑,例如分页、排序等。
通过上述设计和实现,你可以有效地存储和检索用户的详细信息,并将其与点赞列表关联起来。
5、set类型的操作命令
目标
学习set类型的操作命令
概述
在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。Set可包含的最大元素数量是4G,和List类型不同的是,Set集合中不允许出现重复的元素。
常用命令
命令 | 行为 |
---|---|
sadd 键 元素 元素… | 向一个键中添加1个或多个元素 |
smembers 键 | 得到这个集合中所有的元素 |
sismember 键 元素 | 判断指定的元素在集合中是否存在,存在返回1,不存在返回0 |
srem 键 元素 元素… | 通过键删除一个或多个元素 |
sinter key1 [key2] | 返回给定所有集合的交集(集合中都共有的部分) |
应用场景:
-
需要去重的少量信息,比如:身份证信息、手机号码等作为黑名单|白名单;
-
共同好友查询,使用set的交集;
- eg: zhang:{11,22,33,44} lisi:{22,33,66,88}
zhangsan和lisi共同的好友:交集取22 33即可.
- eg: zhang:{11,22,33,44} lisi:{22,33,66,88}
小结
-
添加元素:sadd
-
删除元素:srem
-
得到所有元素:smembers
-
判断元素是否存在:sismember
6、zset/sorted set类型的操作命令
目标
学习zset命令的操作
概述
Redis 有序集合(sorted set)和set集合一样也是无序不可以重复。不同的是每个元素都会关联一个分数(排序因子)。
redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复,每个集合可存储40多亿个成员。
命令
命令 | 行为 |
---|---|
zadd 键 分数 值 分数 值 | 添加1个或多个元素,每个元素都有一个分数 |
zrange 键 开始索引 结束索引 | 获取指定范围的元素,得到所有的元素,索引是0到-1 |
zrange 键 开始索引 结束索引 withscores | 查询指定的元素和对应的分数 |
zrevrange 键 开始索引 结束索引 withscores | 按照分数倒叙获取指定的元素和对应的分数 |
zrem 键 值 值 | 删除一个或多个值 |
zcard 键 | 得到元素个数 |
zrank 键 值 | 得到元素的索引号 |
zscore 键 值 | 得到元素的分数 |
应用场景:
1.b站视频点击量排名
2.新浪热点文章点击量、收藏量等排名
小结
命令 | 行为 |
---|---|
zadd | 添加 |
zrange | 查询 |
zrem | 删除 |
zcard | 个数 |
zrank | 索引号 |
zscore | 得到分数 |
3. Redis的其他操作
1、Redis的通用命令
目标
学习redis中通常的操作命令
常用命令
命令 | 功能 |
---|---|
keys 匹配字符 | 查询所有的键,可以使用通配符 ***** 匹配多个字符 ? 匹配1个字符 |
del 键1 键2 | 删除任何的值类型,而且可以同时删除多个键 |
exists 键 | 判断指定的键是否存在,不存在返回0 存在返回1 |
type 键 | 判断指定的键,值的类型。返回是类型的名字 |
select 数据库编号 | 选择其它的数据库 |
move 键 数据库编号 | 将当前数据库中指定的键移动到另一个数据库中 |
TTL key | 返回给定 key 的剩余生存时间(TTL, time to live),以秒为单位 从Redis2.8开始:如果key不存在或者已过期,返回-2;如果key存在并且没有设置过期时间(永久有效),返回-1 |
flushall | redis的flushall命令用来清空redis所有的库,测试可以使用,开发中最好不要用。 |
小结
-
keys:找到所有的键,通配符: ?*
-
exists:判断指定的键是否存在
-
type:判断指定键值的类型
-
select:切换数据库默认是0-15
-
move:将键移动另一个数据库
-
del: 删除多个键