mysql如何实现简单推荐逻辑_mysql项目入门示例

6次阅读

用 GROUP BY + ORDER BY 可实现无需机器学习库的协同过滤推荐,核心是找相似用户并推荐其高频购买而目标用户未购的商品;需建联合索引、改 NOT IN 为 LEFT JOIN、分步处理稀疏行为,并为冷启动设计热门/新品兜底策略。

mysql如何实现简单推荐逻辑_mysql项目入门示例

用 GROUP BY + ORDER BY 实现协同过滤雏形

不需要机器学习库,mysql 本身就能跑出“买了这个的人也买了那些”的基础推荐。核心思路是:找出和目标用户行为相似的其他用户,再取他们买过但目标用户没买过的商品。

假设表结构为 orders(user_id, product_id, created_at),想给用户 123 推荐:

  • 先查出用户 123 购买的全部 product_id
  • 再查所有购买过这些商品的其他用户(排除 123 自己)
  • 统计这些“相似用户”购买频次最高的商品(且不在用户 123 的历史中)
select product_id, count(*) AS cnt FROM orders WHERE user_id IN (   SELECT DISTINCT user_id   FROM orders   WHERE product_id IN (     SELECT product_id FROM orders WHERE user_id = 123   ) AND user_id != 123 ) AND product_id NOT IN (   SELECT product_id FROM orders WHERE user_id = 123 ) GROUP BY product_id ORDER BY cnt DESC LIMIT 5;

避免笛卡尔积导致查询爆炸

上面 SQL 在数据量稍大(比如相似用户超 5000 个)时会变慢,因为子查询嵌套+NOT IN容易触发全表扫描。真实项目中必须加索引,且改写为 LEFT JOIN 避免 NOT INNULL 敏感的问题。

  • 强制建立联合索引:ALTER table orders ADD INDEX idx_uid_pid (user_id, product_id);
  • NOT IN 换成 LEFT JOIN ... IS NULL,更稳定
  • 如果用户行为稀疏(每人只买几个),先用临时表存“种子商品”,再分步关联,比单条 SQL 更可控

冷启动时 fallback 到热门或新品

新用户没任何购买记录,上面逻辑直接返回空。不能卡住,得有兜底策略:

  • 按销量排序:SELECT product_id FROM orders GROUP BY product_id ORDER BY COUNT(*) DESC LIMIT 5
  • 按上架时间倒序(假设你有 products(created_at) 表)
  • 混合策略:热门 × 0.7 + 7 天内新品 × 0.3,用 union ALL 后加 LIMIT 控制总数

注意别在主查询里实时算热度权重,应预计算到缓存表或加字段(如 products.hot_score),否则每次推荐都扫全表。

为什么不用 JOIN 直接连三张 orders 表

有人尝试写三层 JOIN 模拟用户-商品-用户关系链,结果查几秒不出结果甚至 OOM。MySQL 的 JOIN 优化器对多层自连接非常不友好,尤其当 orders 表超百万行时,中间结果集极易膨胀。

  • 用子查询明确切分步骤,让执行计划更可控
  • 每步加 LIMIT(比如先取 top 100 相似用户)可大幅提速,牺牲一点精度换响应时间
  • 真正上线前务必用 EXPLaiN format=TREE 看是否走了索引,以及 rows 估算是否合理

推荐逻辑越简单,越要盯死执行计划和实际耗时——看起来一行 SQL 很轻量,背后可能扫千万行。

text=ZqhQzanResources