ThinkPhp5 中 排行榜的设计

in ThinkPhp with 1 comment

ThinkPhp排行榜的设计

需求分析

需求实现

首先,我们来对比一下 Redis 和 mysql 的区别

Redis 支持 string 、 hash 、 list 、 set 、 sort set 等多种数据结构,并以内存的形式存储数据,且可持久化到本地中

mysql 则是存放在数据库中,在高并发的场景下需要极度依赖于硬件及其他各种优化情况

具体的对比我就不加分析

同时根据需求,我们需要存储的数据有 排名数据、折扣信息 这两样, 所以我们需要寻找合适的结构来保存


数据结构的选择

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。

使用存储对象、可以保存大量的 键值对、可以当个修改 字段信息值,这些都是保存对象和数组的好玩意

用来保存折扣信息

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

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

是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

分析: 排行需要进行自动排行减少查找等操作、需要进行保存大量的成员key值, 同时可以根据自定义的分数进行修改排行位置,所以 sorted set 是最适合的结构

功能刨析分块实现

由于 排行榜 、 redis 是扩展方法,所以采用 server 层来保存数据

这里使用的由于是 tp5 所以采用的是phpredis

- 置顶功能

    /**
* * 置顶功能
*
@parammixed $mix_id 折扣的id,可数组可int
*
@parambool $isCache 是否为取消排行
*
@returnint 返回的是置顶成功的条数
*
@throws\think\Exception
*
@throws\think\db\exception\DataNotFoundException
*
@throws\think\db\exception\ModelNotFoundException
*
@throws\think\exception\DbException
*/
public functionrank_stick($ids, $cid ='*', $isCache = false){ $ids = \json_decode($ids, true); $susses_len = 0; foreach ($ids as $id) { # 分类id $discount = Discount::where('id', $id)->field('category_id')->find(); if( $discount ) { # 确保数据存在更新分数 $discount = $this->getDiscountByRedis($id, $cid); # 从缓存中读取redis信息 $score = $this->getScorestByCategory($cid); # 当前分类最高的分数 if( !is_null($discount) && $score ) { # 取消置顶 if( $isCache ) { $this->update_rank($discount); ++ $susses_len; }else{ $this->insert_rank($discount, $score + 1); # 在基础上加1 ++ $susses_len; } } } } return $susses_len; }
Comments are closed.