设计浏览记录存储方案

Posted tracydzf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计浏览记录存储方案相关的知识,希望对你有一定的参考价值。

当登录用户在浏览商品的详情页时,我们就可以把这件商品信息存储起来,作为登录用户的浏览记录。
用户未登录,我们不记录其商品浏览记录。

1. 存储数据说明

虽然浏览记录界面上要展示商品的一些SKU信息,但是我们在存储时没有必要存很多SKU信息。
我们选择存储SKU信息的唯一编号(sku_id)来表示该件商品的浏览记录。
存储数据:sku_id

2. 存储位置说明

  • 用户浏览记录是临时数据,且经常变化,数据量不大,所以我们选择内存型数据库进行存储。
  • 存储位置:Redis数据库 3号库
CACHES = {
    "history": { # 用户浏览记录
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/3",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
}

3. 存储类型说明

由于用户浏览记录跟用户浏览商品详情的顺序有关,所以我们选择使用Redis中的list类型存储 sku_id
每个用户维护一条浏览记录,且浏览记录都是独立存储的,不能共用。所以我们需要对用户的浏览记录进行唯一标识。
我们可以使用登录用户的ID来唯一标识该用户的浏览记录。
存储类型:history_user_id : [sku_id_1, sku_id_2, ...]

技术图片

4. 存储逻辑说明

SKU信息不能重复。
最近一次浏览的商品SKU信息排在最前面,以此类推。
每个用户的浏览记录最多存储五个商品SKU信息。
存储逻辑:先去重,再存储,最后截取。

保存用户浏览记录

class UserBrowseHistory(View):
    """用户浏览记录"""

    def post(self, request):
        """保存用户浏览记录"""
        # 接收参数
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get(sku_id)

        # 校验参数:
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.HttpResponseForbidden(sku不存在)

        # 保存用户浏览数据
        redis_conn = get_redis_connection(history)
        pl = redis_conn.pipeline()
        user_id = request.user.id

        # 先去重: 这里给 0 代表去除所有的 sku_id
        pl.lrem(history_%s % user_id, 0, sku_id)
        # 再存储
        pl.lpush(history_%s % user_id, sku_id)
        # 最后截取: 界面有限, 只保留 5 个
        pl.ltrim(history_%s % user_id, 0, 4)
        # 执行管道
        pl.execute()

        # 响应结果
        return http.JsonResponse({code: 0, 
                                  errmsg: OK})

查询用户浏览记录

class UserBrowseHistory(View):
    """用户浏览记录"""

    def get(self, request):
        """获取用户浏览记录"""
        # 获取Redis存储的sku_id列表信息
        redis_conn = get_redis_connection(history)
        sku_ids = redis_conn.lrange(history_%s % request.user.id, 0, -1)

        # 根据sku_ids列表数据,查询出商品sku信息
        skus = []
        for sku_id in sku_ids:
            sku = SKU.objects.get(id=sku_id)
            skus.append({
                id: sku.id,
                name: sku.name,
                default_image_url: sku.default_image_url,
                price: sku.price
            })

        return http.JsonResponse({code: 0, 
                                  errmsg: OK, 
                                  skus: skus})

 

以上是关于设计浏览记录存储方案的主要内容,如果未能解决你的问题,请参考以下文章

十条实用的jQuery代码片段

Redis百亿级Key存储设计方案

美多商城之商品

用于从 cloudkit 检索单列的代码模式/片段

LeetCode Algorithm 1472. 设计浏览器历史记录

LeetCode Algorithm 1472. 设计浏览器历史记录