String类型数据的扩展操作
业务场景一
大型企业级应用中,分表操作是基本操作,使用多张表存储同类型数据,但是对应的主键id必须保证统一性,不能重复。Oracle数据库有Sequence的设定,可以解决该问题,但MySQL数据库并不具有类似的机制,那么该如何解决?
redis, 把原来的一张表分成若干表,并保证所有的id都不重复; 找另一方控制不重复就行了;
解决方案
- 设置数值数据增加指定范围的值
|
|
- 设置数值数据减少指定范围的值
|
|
string作为数值操作
-
string在redis内部存储默认就是一个字符串,当遇到增减类操作incr, decr时就会转成数值型进行计算;
-
redis所有的操作都是原子性的,采用单线程来处理所有的业务,命令是一个一个的执行的,因此无需考虑并发带来的数据影响;
-
注意: 按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis数值的上限范围,将报错。
9223372036854775807 (java中long型数据的最大值, Long.MAX_VALUE)
Tips1:
- redis用于控制数据库表主键id, 为数据库表主键提供生成策略,保障数据库表的主键唯一性;
- 此方案适用于所有数据库,且支持数据库集群;
业务场景二
“最强女生” 启动海选投票, 只能通过微信投票, 每个微信号每4小时只能投一票;
电商商家开启热门商品推荐, 热门商品不能一直处于热门期, 每种商品热门期维持3天, 3天后自动取消热门;
新闻网站会出现热点新闻,热点新闻最大的特征是时效性, 如何自动控制热点新闻的时效性;
new_id: HB314790725;
解决方案
- 设置数据具有指定的生命周期
|
|
秒, 毫秒
127.0.0.1:6379> setex tel 10 1 OK 127.0.0.1:6379> get tel “1” 127.0.0.1:6379> get tel “1” 127.0.0.1:6379> get tel (nil)
Tips2:
- Redis控制数据的生命周期, 通过数据是否失效控制业务行为, 适用于所有具有时效性限定控制的操作;
String类型数据操作的注意事项
String类型应用场景
- 主页高频访问信息显示控制, 例如新浪微博大V主页显示粉丝数与微博数量;
key的设置约定
- 数据库中的热点数据key命名惯例
表名 | 主键名 | 主键值 | 字段名 | |
---|---|---|---|---|
eg1 | order | id | 29437595 | name |
eg2 | equip | id | 39047234 | type |
eg3 | news | id | 20200415 | title |
Hash数据类型
存储的困惑
对象类数据的存储,如果具有较频繁的更新需求操作会显得笨重;
key, field, value; 这就是hash;
- 新的存储需求:对一系列存储的数据进行编组,方便管理, 典型应用存储对象信息;
- 需要的存储结构: 一个存储空间保存多个键值对数据;
- hash类型: 底层使用哈希表结构实现数据存储;
hash类型数据的基本操作
-
添加 / 修改数据
hset key field value
-
获取数据
hget key field
hgetall key
-
删除数据
hdel key field1 [field2]
|
|
-
添加 / 修改多个数据
hmset key field1 value1 field2 value2
-
获取多个数据
hmget key field1 field2
-
获取哈希表中字段的数量
hlen key
-
获取哈希表中是否存在指定的字段
hexists key field
hash类型数据扩展操作
- 获取哈希表中所有的字段名或字段值
|
|
- 设置指定字段的数值数据增加指定范围的值
|
|
hash类型应用场景
业务场景
电商网站购物车设计实现
用户id =key, 商品id = field, 数量: value
业务分析
-
仅分析购物车的redis存储模型
添加,浏览,更改数量,删除,清空
-
购物车与数据库间持久化同步(不讨论)
-
购物车与订单间关系(不讨论)
提交购物车: 读取数据生成订单
商家临时价格调整: 隶属于订单级别
-
未登录用户购物车信息存储(不讨论)
cookie存储
解决方案
- 以客户id作为key, 每位客户创建一个hash存储结构存储对应的购物车信息;
- 将商品编号作为field, 购买数量作为value进行存储;
- 添加商品, 追加全新的field与value;
- 浏览: 遍历hash;
- 更改数量: 自增 / 自减, 设置value值;
- 删除商品: 删除field;
- 清空: 删除key;
当前仅仅是将数据存储到了redis, 并没有起到加速的作用, 商品的信息还需要二次到数据库中去查;
field2 应该单独拿出来作为商品的一个hash;会避免数据的重复存储;
hsetnx key field value
有值不加进去, 没有就加进去;
业务场景
string存储对象(json)(读操作灵活), 与hash存储对象 (更新操作灵活)
list数据类型
list类型
- 数据存储要求: 存储多个数据,并对数据进入存储空间的顺序进行区分;
- 需要的存储结构:一个存储空间保存多个数据,
- list类型: 保存多个数据,底层使用双向链表存储结构实现;
顺序表
头指针 huawei tencent alibaba apple, 插入CNPC
list类型数据基本操作
-
添加 / 修改数据
lpush key value1 [value2] ...
-
获取数据
lrange key start stop
lindex key index
llen key
-
删除数据
lpop key
rpop key
list类型数据扩展操作
-
规定时间内获取并移除操作
bpop key1 [key2] timeout
bpop key1 [key2] timeout
b是block的意思, 阻塞多少秒之后pop;
list类型数据业务背景
业务背景
微信朋友圈点赞, 要求按照点赞顺序显示点赞好友的信息;
如果取消点赞,移除对应好友信息;
解决方案:
-
移除指定数据
lrem key count value
Tips:
- redis应用于具有操作先后顺序的数据控制
list类型数据操作注意事项
- list保存的数据都是string类型的, 数据总容量是有限的, 最多2^32 -1个元素(4,294,967,295)
- list具有索引的概念, 但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作;
- 获取全部数据操作结束索引设置为-1;
- list可以对数据进行分页操作,通常第一页的信息来自于list, 第2页及更多的信息通过数据库的形式加载;
业务场景:
1.Twitter, 微博中个人用户的关注列表需要按照用户的关注顺序进行展示,粉丝列表需要将最近关注的粉丝列在前面;
2.新闻, 资讯类网站如何将最近的新闻或资讯按照发生的时间顺序展示?
3.企业运营过程中,系统将产生出大量的运营数据,如何保障多台服务器操作日志的统一顺序输出?
解决方案
- 依赖list的数据具有顺序的特征对信息进行管理
- 使用队列模型解决多路信息汇总合并的问题
- 使用栈模型解决最新消息的问题
Tips: redis应用于最新信息展示;
Set数据类型
-
新的存储要求: 存储大量的数据, 在查询方面提供更高的效率;
-
需要的存储结构: 能够保存大量的数据, 高效的内部存储机制, 便于查询;
-
set类型:与hash存储结构完全相同,仅存储键, 不存储值nil, 并且值是不允许重复;
Set类型数据的基本操作
- 添加数据
|
|
- 获取全部数据
|
|
- 删除数据
|
|
- 获取集合数据总量
|
|
- 判断集合中是否包含指定数据
|
|
Set类型数据扩展操作
业务场景
每位用户首次使用今日头条时会设置3项爱好的内容, 但是后期为了增加用户的活跃度、兴趣点,必须让用户对其他信息类别逐渐产生兴趣,增加客户留存度, 如何实现?
业务分析
- 系统分析出各个分类的最新或最热点信息条目并组织成set集合;
- 随机挑选其中的部分信息;
- 配合用户关注信息分类中的热点信息组织成展示的全信息集合;
解决方案
-
随机获取集合中指定数量的数据
srandmember key [count]
-
随机获取集合中的某个数据并将该数据移出集合
spop key
Tips8:
redis应用于随机推荐类信息检索, 例如热点歌单推荐,热点新闻推荐, 热卖旅游线路,应用APP推荐,大V推荐等
业务场景
脉脉为了促进用户间的交流, 保障业务成单率的提升, 需要让每位用户拥有大量的好友,事实上职场新人不具有更多的职场好友, 如何快速的为用户积累更多的好友?
新浪微博为了增加用户的热度, 提高用户的留存性
解决方案
-
求两个集合的交, 并, 差集
sinter key1 [key2]
sunion key1 [key2]
sdiff key1 [key2]
-
求两个集合的交,并, 差集并存储到指定集合中
sinterstore destination key1 [key2]
sunionstore desitination key1 [key2]
sdiffstore destination key1 [key2]
-
将指定数据从原始集合移动到目标集合中
smove souece destination member
Tips9:
- redis应用于同类信息的关联检索, 二度关联检索, 深度关联检索;
- 显示共同关注(一度)
- 显示共同好友(一度)
- 由用户A出发, 获取到好友用户B的好友信息列表(一度)
- 由用户A 出发, 获取到好友用户B的购物清单列表(二度)
- 由用户A 出发, 获取到好友用户B的游戏充值列表(二度)
注意事项:
- SEI类型不允许数据重复;
- set虽然与hash的存储结构相同,但是无法启用hash中存储的空间;
Set型数据业务场景
sadd rid:001 getall
sadd rid:001 getById
sadd rid:002 getCount
sadd rid:002 getall
sadd rid:002 insert
sunionstore uid:007 rid:001 rid:002
sismembers uid:007 insert
redis应当是提供基础数据, 而不要提供检验结果(含业务逻辑, 业务逻辑应该放在调用端去实现);
Tip10:
redis应用于同类型 不重复数据的合并操作;
业务场景
公司对旗下新的网站做推广,统计网站的PV(访问量), UV(独立访客),IP(独立IP)。
PV: 网站被访问次数, 可通过刷新页面提高访问量;
UV: 网站被不同用户访问的次数, 可通过Cookie统计访问量, 相同用户切换IP地址, UV不变;
IP: 网站被不同IP地址访问的总次数, 可通过IP地址统计访问量, 相同IP不同用户访问, IP不变;
Tips:
redis应用于同类型数据的快速去重;
Tips12: redis应用于基于黑名单和白名单的设定限制;
sorted_set类型
- 新的存储需求: 数据排序有利于数据的有效展示,需要提供一种可以根据自身特征进行排序的方式;
- 需要的存储结构:新的存储模型, 可以保存可排序的数据;
- sorted_set类型: 在set的存储结构基础上添加可排序字段
sorted_set类型数据的基本操作
- 添加数据
|
|
- 获取全部数据
|
|
- 删除数据
|
|
- 按条件获取数据
|
|
- 条件删除数据
|
|
min与max用于限定搜索查询的条件;
start与stop用于限定查询范围, 作用域索引, 表示开始和结束索引;
offset与count用于限定查询范围(limit), 作用于查询结果, 表示开始位置和数据总量;
-
获取集合数据总量
1 2
zcard key zcount key min max
-
集合交,并操作
1 2
zinterstore destination numkeys key [key ...] zunionstore destination numkeys key [key ...]
sorted_set类型数据扩展操作
业务场景
票选广东十大杰出青年, 各类综艺选秀海选投票,各类资源网站TOp10(电影, 歌曲,文档,电商,游戏等),聊天室活跃度统计,游戏好友亲密度等
业务分析
- 为所有参与排名的资源建立排序资源
解决方案
- 获取数据对应的索引(排名)
|
|
- score值获取与修改
|
|
**Tips:**redis应用于计数器组合排序功能的排名
业务场景
基础服务+增值服务类网站会设定各位会员的试用,让用户充分体验会员优势。例如观影试用VIP, 游戏VIP体验, 云盘下载体验VIP, 数据查看体验VIP。当VIP体验到期后,如何有效管理此类信息。 即便对于正式VIP用户也存在对应的管理方式。
网站会定期开启投票、讨论,限时进行,逾期作废。如何有效管理此类过期信息;
Tip14: redis应用于定时任务执行顺序管理或任务过期管理;
sorted_set数据业务场景
任务 / 消息权重设定应用
当任务或者消息待处理, 形成了任务队列或者消息队列时, 对于高优先级的任务要保障对其优先处理, 如何实现任务权重管理;
解决方案
对于带权重的任务, 优先处理权重高的任务,采用score记录权重即可;
数据实践案例
场景一
业务场景
人工智能领域的语义识别与自动对话将是未来服务业机器人应答呼叫体系中的重要技术,百度自研用户评价语义识别服务, 免费开放给企业试用, 同时训练百度自己的模型。现对试用用户的使用行为进行限速, 限制每个用户每分钟最多发起10次调用;
tips : redis应用于限时按次结算的服务控制
场景二
微信会话的顺序(消息应该是按什么顺序?)
Tips17: redis应用于基于时间顺序的数据操作, 而不关注具体时间;