
怎么存最近搜索记录:用一张带时间戳的表最靠谱
直接建表,别用 JSON 字段或拼接字符串存历史——查起来慢、排序难、没法加索引。核心就三点:用户标识、搜索词、时间。
-
user_id(非空,关联用户,没登录就用session_id或ip_hash临时标识) -
keyword(VARCHAR(255)足够,别用TEXT,影响索引效率) -
created_at(DATETIME或TIMESTAMP,必须有,否则“最近”无从谈起) - 加联合索引:
INDEX idx_user_time (user_id, created_at),查某人最近 N 条才快
插入时怎么避免重复和爆表:加限制比事后清理更省事
用户狂输“java”“Java”“JAVA”,不该全留;连续搜三次“mysql”,也不该记三条。重点不是“去重”,而是“有意义地收敛”。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 写入前先
SELECT COUNT(*)查过去 10 分钟内同user_id+ 同LOWER(keyword)是否已存在,有就跳过(或只更新created_at) - 插入后立刻
DELETE FROM search_history WHERE user_id = ? AND created_at ,保留一周足够,别等磁盘报警 - 加个
ON DUPLICATE KEY UPDATE created_at = NOW()前提是(user_id, keyword)有唯一索引——但注意:这会让“同一词多次搜索”只保留最后一次,得想清楚业务是否接受
查最近 10 条怎么写才不翻车:ORDER BY + LIMIT 是基础,但容易漏掉条件
常见错误是只写 ORDER BY created_at DESC LIMIT 10,结果把所有用户的记录混在一起返回。必须带上 WHERE user_id = ?,否则数据错乱。
- 正确写法:
SELECT keyword FROM search_history WHERE user_id = ? ORDER BY created_at DESC LIMIT 10 - 如果要支持“忽略大小写去重显示”,得在应用层处理(MySQL 8.0+ 可用
ROW_NUMBER() OVER (PARTITION BY LOWER(keyword) ORDER BY created_at DESC),但性能敏感场景慎用) - 别在 SQL 里做
LIKE '%xxx%'模糊查历史——那是搜索功能本身的事,不是查“历史”的逻辑
没登录用户的历史怎么存:session_id 不可靠,得有 fallback
session_id 随浏览器关闭消失,用户换个设备就断档。真要保体验,得组合策略。
- 优先用
session_id,写入时加is_anonymous = 1字段标记 - 同时生成一个轻量级设备指纹(比如
UA+screen.width+timezone的哈希),存进fingerprint字段,有效期设为 30 天 - 查历史时,先按
session_id查,查不到再按fingerprint查——但注意:不能仅依赖 fingerprint,隐私合规要求你明确告知并允许用户拒绝
weight,初始全设为 1,后续想按点击量加权、按停留时长衰减,都还有余地。

















