首页 > 解决方案 > 每天查看计数器的 SQL 数据库结构

问题描述

我们希望为每个帖子创建一个查看计数器(https://my-domain.com/posts/post-title),并且我们希望存储每天的浏览量,以允许帖子按“过去 7 天最受欢迎”排序、“最近 30 天内最受欢迎”等。我们可以使用多种解决方案。

解决方案 A: 有一个包含以下列的“ view_counters ”表:

id
post_id INT
08_28_2020 INT DEFAULT 0
08_29_2020 INT DEFAULT 0
08_30_2020 INT DEFAULT 0
08_31_2020 INT DEFAULT 0
...

每天,PHP 中的 cron 作业都会添加一个以今天的日期为名称的列。每个帖子会有一行。对于每个视图,我们将按当前日期增加列。该解决方案允许通过 Web 界面 (PhpMyAdmin) 为人类提供更易于阅读的内容,但仍会创建大量列,并且它可能不是数据库引擎最优化的解决方案。因为 1 年后表中将有超过 365 列。


解决方案 B: 有一个包含以下列的“ view_counters ”表:

id
post_id INT
current_date DATE
counter INT DEFAULT 0

每天每个帖子会有一行。在每个视图中,我们都会增加相关帖子行的“计数器”列。诚然,通过 PhpMyAdmin 的可读性较差(您必须进行一个小查询),但对于数据库引擎来说,它肯定更容易阅读和处理。如果我说错了请纠正我!


解决方案 C: 有一个包含以下列的“ view_counters ”表:

id
post_id INT
current_date DATE

每个视图都会向表中添加一行。然后,我们将有一个查询,该查询将计算当前日期的此类帖子的查看次数(使用 COUNT())。但是,我们认为这种解决方案并不合适,因为每次访问者加载帖子页面时都需要执行一次 COUNT(),因为我们知道我们每天的浏览量超过 100,000 次,这会占用大量资源每次都要重新计算。因此,我们认为解决方案不适合...


解决方案 D: 如果您有其他结构更优化的解决方案,我很想了解更多!

希望是清晰易懂的。预先感谢您的回答!

标签: mysqlsqldatabase-design

解决方案


B,但更简单

post_id INT
date DATE   -- (there is nothing "current" about the date")
counter INT DEFAULT 0

也就是说,摆脱id,因为你应该拥有它是没有用的PRIMARY KEY(post_id, date)

每天晚上计算当天的计数。

你有一个“汇总表”。更多讨论:http: //mysql.rjweb.org/doc.php/summarytables

“报告”将汇总计数以获得任何(每周/每月/任何)日期范围的总数。然后,“最受欢迎”建立在拥有这些数量的基础上。

C

“每次访问者加载页面时都需要执行一次 COUNT()”——这不是一个真正的问题;它可以使用 IODKU 处理,它可以添加新行(每天一次,每个帖子)或更新现有行。

IODKU 是使用代码进行日常总结的替代方案。注意:我的表模式适用于 IODKU。此外,每天 10 万次点击是“微不足道的”。如果达到 10M/天,您可能需要切换到每晚汇总。

经验法则:低于 100 个查询/秒不是问题;更多的可能需要特殊处理。

一个

跨列传播“数组”几乎总是一个坏主意。


推荐阅读