这是我目前的结构:
// posts
+----+--------+----------+-----------+------------+
| id | title | content | author_id | date_time |
+----+--------+----------+-----------+------------+
| 1 | title1 | content1 | 435 | 1468111492 |
| 2 | title2 | content2 | 657 | 1468113910 |
| 3 | title3 | content3 | 712 | 1468113791 |
+----+--------+----------+-----------+------------+
// viewed
+----+---------------+---------+------------+
| id | user_id_or_ip | post_id | date_tiem |
+----+---------------+---------+------------+
| 1 | 324 | 1 | 1468111493 |
| 2 | 546 | 3 | 1468111661 |
| 3 | 135.54.12.1 | 1 | 1468111691 |
| 5 | 75 | 1 | 1468112342 |
| 6 | 56.26.32.1 | 2 | 1468113190 |
| 7 | 56.26.32.1 | 3 | 1468113194 |
| 5 | 75 | 2 | 1468112612 |
+----+---------------+---------+------------+
这是我的查询:
SELECT p.*,
(SELECT count(*) FROM viewed WHERE post_id = :id) AS total_viewed
FROM posts p
WHERE id = :id
目前我面临着一个巨大的viewed
餐桌约会。那么我的表结构(或数据库设计)有什么问题吗?换句话说,我该如何改进它?
像 stackoverflow 这样的网站有近 1200 万个帖子。每个帖子都有(平均) 500 次浏览。所以的viewed
行数应该是:
12000000 * 500 = 6,000,000,000 rows
哈:-)
.. 老实说,我什至看不懂那个数字(顺便说一句,这个数字每秒都会增长)。那么 stackoverflow 如何处理每个帖子的查看次数?它总是根据每个帖子的显示来计算count(*)
吗viewed
?
是什么让您认为
viewed
在 stackoverflow 的数据库中有一个像您这样的表?原始日志在关系数据库上的维护成本非常高,而在高流量网站上,缓存具有非常重要的作用,几乎不可能保存所有内容的完整日志(已汇总)。例如,对于维基百科,我们维护一个完全不同的分析基础架构(由来自 Varnish 和 Mediawiki 的 Apache Kafka 提供支持),然后提供一个可以从 Mediawiki 本身调用的 API:https ://tools.wmflabs.org/pageviews /?project=en.wikipedia.org&platform=all-access&agent=user&range=latest-20&pages=Main_Page如果您必须在数据库中实现
viewed X times
功能,您可以通过维护一个额外的列作为主帖子表的一部分来对表进行非规范化:出于多种原因,在某些情况下可能更喜欢单独的表(例如,避免使主表变热;如果有一个非常规范化的表,例如 post_properties;如果大多数帖子的视图为 0,则可以节省空间)——这完全取决于外部因素。在这种情况下,您将拥有:
接着:
(这
LEFT JOIN
是为了防止你的帖子没有浏览量,如果没有,就使用常规的JOIN
)在这两种情况下,在添加“视图”之后,额外(或替代地)以 SERIALIZED 方式将视图数加 1。
尽量避免在关系数据库(特别是 MySQL)上记录日志。您可以在分析后将摘要带回来。