【问题标题】:Page hits counter - Am I overexerting the database?页面点击计数器 - 我是否过度使用数据库?
【发布时间】:2015-05-18 16:06:11
【问题描述】:

我在我的网站上构建了一个简单的计数器(PHP 和 MySQL,使用 Codeigniter 作为我的框架)。

这是我使用的表格:

CREATE TABLE page_hits (id INT NOT NULL AUTO_INCREMENT, page_url VARCHAR(350) NOT NULL, ip VARCHAR(11) NOT NULL, hits INT NOT NULL, `date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP  NOT NULL, PRIMARY KEY (id));

在每次页面加载时,我都会检查表中是否存在 page_urlip 的组合。如果是,我将hits 的值增加1。如果不是,我在表中创建一个新行。时间戳允许命中计数之间存在一定的延迟,以免将页面刷新计为新命中。

一切都很好,但我担心我的数据库可能会超载... 在不到 24 小时内,page_hits 表中有超过 6500 行。

所以我的问题是:在我的数据库中拥有如此快速增长的表有什么风险? (性能问题?超出数据库大小限制?)

【问题讨论】:

  • 如果您的表经过规范化和正确索引,您不会冒任何风险。

标签: php mysql hitcounter


【解决方案1】:

让我从重写你的单行 SQL 命令开始:

CREATE TABLE page_hits 
(id       INT NOT NULL AUTO_INCREMENT, 
 page_url VARCHAR(350) NOT NULL, 
 ip       VARCHAR(11) NOT NULL, 
 hits     INT NOT NULL, 
 date     TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 
 PRIMARY KEY (id))

现在我可以看到那里有什么了。

您的表并不复杂,但会快速增长。这不会是一个问题,只要你不做任何事情。换句话说:向表中添加行不是问题,即使您有一百万行。

但是,一旦您开始查询此表,您就会发现它很快就会变慢。您忘记添加索引了。

How do I add indices to MySQL tables?

其次,您可以考虑规范化您的表格并删除不需要的信息。例如这三个较小的表:

CREATE TABLE page_hits 
    (id         INT NOT NULL AUTO_INCREMENT, 
     page_id    INT NOT NULL, 
     client_id  INT NOT NULL, 
     hits       INT NOT NULL, 
     PRIMARY KEY (id))

CREATE TABLE pages 
    (id       INT NOT NULL AUTO_INCREMENT, 
     page_url VARCHAR(350) NOT NULL, 
     PRIMARY KEY (id))

CREATE TABLE clients 
    (id       INT NOT NULL AUTO_INCREMENT, 
     ip       VARCHAR(11) NOT NULL, 
     date     TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, 
     PRIMARY KEY (id))

这里page_id 指的是pages 表,client_id 指的是clients 表。您必须自己添加索引。我会去掉date 列,并用cookie 解决这个问题。请注意,新表可以轻松扩展以包含更多信息,而不会很快变得太大。

【讨论】:

  • 谢谢!并为我原来的帖子中糟糕的 SQL 布局感到抱歉。
  • 它被否决了。如果它保持这种状态,我将删除此答案。如果我知道自己做错了什么,我会有所帮助,这样我就可以提高自己。
  • 我现在在page_urlip 上添加了索引,因为这些是我将要查询的字段。但我不明白使用三个单独的表格而不是我正在使用的表格有什么好处。这种标准化会提高性能吗?
  • 关于你的问题:想想看,任何人的每一次点击都会在page_hits 表中创建一个新行。通过从该表中删除page_urlip,我使每一行都变小了很多。而另外两个表(pagesclients)不会增长得那么快,因为您重用了这些行。这就是规范化的本质。
  • 在 SELECT 命令的 WHERE 部分中使用的列当然需要被索引。每天 7000 行,每年 250 万行。如果您收集几年的数据,那么我认为这有点多。 MySQL 可以轻松处理 1000 万行,但如果您查看数据库文件大小,您可能会明白为什么它会成为问题。假设您的行是 400 字节,将其乘以 1000 万,即 4 GB。太大了,在我看来。我的行大约是那个大小的 1/20。这一切都没有任何索引,这只会使文件变大。
猜你喜欢
  • 2012-03-04
  • 1970-01-01
  • 2011-01-20
  • 2017-07-20
  • 2011-03-19
  • 1970-01-01
  • 2015-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多