mysql如何实现搜索历史功能_mysql项目数据设计

来源:这里教程网 时间:2026-02-28 20:43:18 作者:

搜索历史该存哪些字段

用户每次输入并提交搜索词,就该记一条记录,核心字段必须有:

user_id
(区分谁搜的)、
keyword
(原始搜索词,注意去首尾空格)、
created_at
(时间戳,用
DATETIME
TIMESTAMP
)。可选但强烈建议加
search_count
(默认 1,后续可合并重复词)、
is_deleted
(软删除标记,避免真删影响统计)。

别存

result_count
response_time
这类衍生数据——它们随业务逻辑变化,不该污染历史表结构。

建表语句怎么写才合理

ENGINE=InnoDB
,主键用自增
id
,但查询主要靠
user_id + created_at
,所以要建联合索引。避免用
keyword
做主键或唯一键——用户可能搜相同词多次,且长文本索引效率低。

CREATE TABLE `search_history` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `user_id` BIGINT UNSIGNED NOT NULL,
  `keyword` VARCHAR(255) NOT NULL,
  `search_count` INT UNSIGNED DEFAULT 1,
  `is_deleted` TINYINT UNSIGNED DEFAULT 0,
  `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  INDEX `idx_user_time` (`user_id`, `created_at` DESC),
  INDEX `idx_user_keyword` (`user_id`, `keyword`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

注意:

VARCHAR(255)
足够覆盖绝大多数搜索词;
utf8mb4
支持 emoji 和生僻字;
DESC
在索引里对分页查最新记录有帮助。

插入时怎么避免重复记录

不是所有重复都要合并——用户连续搜“苹果”两次,是两条独立行为。但若想支持「合并同类项」(比如展示“苹果(3次)”),得用

INSERT ... ON DUPLICATE KEY UPDATE
,前提是
user_id + keyword
有唯一约束:

先加唯一索引:

ALTER TABLE search_history ADD UNIQUE KEY `uk_user_keyword` (`user_id`, `keyword`);

再执行插入:

INSERT INTO search_history (user_id, keyword, search_count, created_at) 
VALUES (123, 'mysql优化', 1, NOW()) 
ON DUPLICATE KEY UPDATE 
  search_count = search_count + 1, 
  created_at = NOW();

⚠️ 注意:加唯一索引后,如果业务允许同一用户反复搜相同词但保留多条记录(如分析搜索频次分布),就别用这个方案,改用普通

INSERT
+ 后续聚合查询。

查最近 10 条怎么写不出错

直接

ORDER BY created_at DESC LIMIT 10
是常见写法,但要注意两点:

必须走
idx_user_time
索引,否则全表扫描——确认
EXPLAIN
显示
key
列为该索引
如果用户删过历史,要加
WHERE is_deleted = 0
过滤,否则软删除失效

正确示例:

SELECT keyword, search_count, created_at 
FROM search_history 
WHERE user_id = 123 AND is_deleted = 0 
ORDER BY created_at DESC 
LIMIT 10;

别在应用层做排序和截断——数据库没加

ORDER BY
时,
LIMIT
返回顺序不保证,尤其分库分表后更危险。

实际最难的不是建表或查数据,是决定什么时候清理旧记录。自动定时删?按用户配额限制条数?这些策略得和业务方对齐,数据库只负责高效存取,别替产品做决策。

相关推荐