如何实现网站历史浏览记录:无冗余、支持排序与推荐
解决方案
首先调整views表的结构,只存储关联信息而非重复的商品数据,推荐结构:
user_id:登录用户的ID(关联用户表)listing_id:商品的ID(关联listings表)view_date:浏览时间,设置为自动更新或插入时赋值- 给
(user_id, listing_id)添加唯一约束,避免同一用户重复存储同一商品的浏览记录
1. 处理浏览记录的写入
当用户点击商品时,用INSERT ... ON DUPLICATE KEY UPDATE语句自动更新最新浏览时间,无需事后删除重复数据:
INSERT INTO views (user_id, listing_id, view_date) VALUES ('当前登录用户ID', '点击的商品ID', NOW()) ON DUPLICATE KEY UPDATE view_date = NOW();
2. 查询用户浏览过的商品数据
使用JOIN关联views和listings表,既能获取完整的商品信息,又能按浏览时间正确排序:
SELECT l.*, v.view_date FROM views v INNER JOIN listings l ON v.listing_id = l.id WHERE v.user_id = '当前登录用户ID' ORDER BY v.view_date DESC;
- 用
INNER JOIN只会返回存在于listings表中的商品(若商品被删除,对应浏览记录会被过滤) - 按
v.view_date DESC排序,可得到用户最近浏览的商品在前的结果
为什么之前的IN子查询无效?
IN子查询仅返回一组商品ID,外层SELECT * FROM listings会按照listings表自身的默认顺序(比如主键ID)返回数据,不会遵循子查询中的ORDER BY。而JOIN可以保留views表的浏览时间字段,直接基于该字段排序,同时关联获取商品的完整信息。
这种方案既避免了重复存储商品数据,又能灵活获取浏览记录,后续做个性化推荐时,也可以直接基于views表的用户-商品关联数据进行分析。
内容的提问来源于stack exchange,提问作者Logan M
相关产品推荐
相关产品推荐

