如何在MySQL中正确设计页面访问与按钮点击统计数据表
适配现有MySQL+Laravel技术栈的最优落地方案
你最初的两张明细表设计直接上线会有明显的性能问题:单表日增2000万条的情况下,跑满1个月单表数据量就破6亿,哪怕加了索引,做日期范围、多维度统计时的临时分组计算会直接拖垮数据库,而且绝大多数原始明细数据用户根本不会逐行查询,全量长期存储的性价比极低。
完全不需要额外引入ES、ClickHouse这类重组件,基于你现有技术栈做三层存储架构就能扛住所有业务需求,运维成本几乎为0:
1. 高并发写入层:Redis缓冲削峰
- 不要在用户访问页面、点击按钮的请求链路里直接写MySQL,先把原始日志(UA、IP、page_id/button_id、请求时间)写入Redis List做缓冲,Laravel里跑一个定时任务每1~2分钟批量拉取缓冲数据,一次性批量写入MySQL原始明细表,批量插入的性能是单条循环插入的100倍以上,完全扛得住峰值写入压力。
- 加一层简单的防刷逻辑:同一个IP1分钟内重复访问同一页面、重复点击同一按钮不重复记录,用Redis存1分钟过期的标记位即可,至少能过滤30%的无效刷量数据,降低存储压力。
- UA解析(提取操作系统、浏览器)、IP转国家的逻辑不要放在用户请求链路里执行,等批量刷数据到MySQL的时候再统一处理,避免拖慢用户端的页面加载速度。
2. 在线热数据层:MySQL分表存储
热数据层分两类表,都建在你现有的MySQL实例里:
(1)原始明细表(仅存近7天全量数据)
保留你原来设计的page_visits、button_clicks两张表,必须补上你漏了的核心时间字段created_at(datetime类型),否则根本做不了日期范围筛选。
- 索引只建3个:
(page_id, created_at)、(button_id, created_at)、created_at,不要加多余索引影响写入性能。 - 配Laravel定时任务,每天自动删除7天前的旧明细数据,这部分数据用户查询概率不到1%,没必要长期占用在线库存储。
(2)按天预聚合表(存全周期统计数据,支撑99%的分析查询)
用户要的按浏览器、操作系统、国家、日期维度的统计,完全不需要查原始明细,提前按维度聚合好,查询时毫秒级返回:
- 建
page_visit_stats_daily表,字段包含:id、page_id、stat_date(date类型)、operating_system、browser、country、visit_count(int,当日该维度下的访问量),建唯一联合索引(page_id, stat_date, operating_system, browser, country),更新时直接用INSERT ... ON DUPLICATE KEY UPDATE visit_count = visit_count + 1做原子累加。 - 建
button_click_stats_daily表,字段包含:id、button_id、page_id(冗余存储避免连表查询)、stat_date(date类型)、operating_system、browser、country、click_count(int,当日该维度下的点击量),建唯一联合索引(button_id, page_id, stat_date, operating_system, browser, country)。 - 聚合逻辑和前面的批量刷数任务绑定,每次批量写入原始明细的时候,同步按维度累加更新当天的聚合表数据,不需要额外跑离线计算任务,实现成本极低。
- 这两张聚合表的数据量非常小:1万个页面就算每个页面每天生成100种维度组合,单表日增也才100万条,存3年数据才10亿级别,加对索引的情况下,跨几个月的范围维度查询都是秒级返回,完全满足业务需求。
3. 冷数据归档层(按需开启)
如果业务要求长期留存全量原始明细,不要把超过30天的明细存在线MySQL库,配Laravel定时任务每月把过期的原始明细导出成压缩CSV,存到本地对象存储即可,真有用户需要查询超期明细的时候,再按需导出检索,平时完全不占用在线数据库性能。
Livewire适配注意点
- 所有面向用户的数据分析查询,全部走预聚合表,不要碰原始明细表。比如查询某页面最近30天Chrome浏览器的访问趋势,直接按
page_id、browser、stat_date BETWEEN 起止日期的条件查聚合表,按stat_date分组取数即可,性能比查原始表高几个数量级。 - 不要在Livewire组件的实时刷新逻辑里做重型统计查询,给查询结果加几分钟的Redis缓存,进一步降低数据库压力。
这个方案完全贴合你现有技术栈,不需要额外学习新组件,运维成本和直接用两张表的原始方案几乎一致,但是性能、存储成本、查询效率都能满足未来3年以上的业务增长需求。
内容的提问来源于stack exchange,提问作者Carlos Valdes Web
相关产品推荐
相关产品推荐

