【问题标题】:mysql query if statementmysql查询if语句
【发布时间】:2009-12-20 16:58:43
【问题描述】:

为了简单起见,假设我在 php 中制作了一个基本的浏览量计数器,它将每个页面的计数存储在一个 mysql 表中。该表有 2 个列:PAGE_ID 和 COUNT。

我在每个页面都添加了以下代码:

$query = "INSERT INTO table VALUES ('$page_id', '1')
         ON duplicate KEY UPDATE COUNT=COUNT+1";

$result = mysqli_query($cxn, $query);

为了确保每个查看页面的人只在我添加 PHP 会话后触发计数器。基本上,如果您查看页面,page_id 会存储在会话中,并且计数器 php 代码会在触发计数器之前检查该会话。在我自己的测试中运行良好。

有些页面的浏览量过多,我怀疑重复,所以我开始记录 IP 和用户代理。事实证明,在大约 10% 的情况下,IP 会在几分钟内触发同一页面的计数器 2-3 次。

第一个问题 什么可能导致重复?这个问题似乎主要发生在 IE8 和 Safari 上,但我也至少有一个实例发生在 IE7 和 IE6 上。 php会话有任何已知问题吗?我应该改用 cookie 吗?

第 2 部分: 我修改了我的表,以便它现在存储最后一个 unix 时间戳和触发计数器的最后一个 IP。

我想修改我的查询,以便在它运行“COUNT=COUNT+1”之前检查以下内容:

If the current IP is the same as the last stored IP for this page {

     check that it's been at least 5 minutes before doing COUNT=COUNT+1

} else { COUNT=COUNT+1; }

第二个问题 如何在 mysql 查询中编写它,同时保留我的“ON duplicate KEY”语句?

我知道这个陈述不会 100% 准确,但在我弄清楚为什么会话的事情似乎不起作用之前,这会起作用。我的网站流量很低,在 5 分钟的时间内我很少在同一页面上获得超过 1 个访问者。

谢谢

【问题讨论】:

    标签: php sql mysql counter


    【解决方案1】:

    我建议您尝试查看是否可以修复 PHP,但忽略它。您可以存储 unixtimestamp 除以 300(IE,以 5 分钟为间隔)

    $query = "INSERT INTO OtherTable VALUES ('$page_id', '$IP_ADDRESS', (UNIX_TIMESTAMP(NOW())/300))";

    如果更新的记录为 0,则不需要更新页数。

    【讨论】:

    • 将时间戳分成 5 分钟间隔是个好主意。这不是完全的证明,因为它取决于在 5 分钟的时间范围内第一次计算它的时间。在我看来,这也需要我每次浏览量使用一行。如何使用每个页面 id 一行和一个 mysql 查询使其工作?
    • 如果您将每个 page_id 的密钥设置为唯一,则 ip_address 会明显更小。如果您不这样做,唯一真正的解决方案是修复您的会话处理,这是另一回事。
    【解决方案2】:

    1。什么可能导致重复?

    有些页面的浏览量过多,我怀疑重复,所以我开始记录 IP 和用户代理。事实证明,在大约 10% 的情况下,IP 会在几分钟内触发同一页面的计数器 2-3 次。

    没有办法知道请求页面的主机是否位于 NAT 路由器后面 - 对您而言,请求将具有相同的 IP,但实际上是不同的主机。 cookie 或会话将帮助您在每个工作站的基础上进行隔离,但我想知道您何时将信息写入数据库。

    2。如何在 mysql 查询中编写它,同时保留我的“ON duplicate KEY”语句?

    我认为不需要COUNT = COUNT + 1,因为 SQL 有一个 COUNT 函数:

      SELECT page_id,
             COUNT(*) 'num_hits'
        FROM ZZZ_NETWORK
       WHERE page_id = ?
    GROUP BY page_id
    

    如果您对ZZZ_NETWORK 使用以下结构:

    • page_id,主键
    • ip_address,主键
    • 时间戳,主键

    ...您不必担心重复的密钥处理,它可以让您知道在特定的一天、一周、一个月/等中获得了多少次点击。 包括时间戳将确保永远不会有重复

    一个月后,如果我在每次页面视图中使用一行,我的表中就会有数千行。

    驱动器空间非常便宜,并且具有时间戳以便您可以进行数据挖掘对于报告而言非常宝贵。但是您也不必保留所有数据 - 您可以通过将数据转储到文件来归档它,以便在必要时检索它。

    我不明白它如何确保我永远不会得到重复。

    时间戳包括日期(2009 年 12 月 25 日)和时间(07:00:00 AM)。某些日期时间数据类型可以精确到几分之一秒。这使得具有给定 IP 地址的给定 page_id 具有相同的日期和时间几乎是不可能的 - 即使我愿意,我也无法足够快地单击刷新按钮。所以记录永远不能重复,因为三列中的最后一列每次都会有不同的值(没有双关语)。

    【讨论】:

    • 感谢您的回复。您必须记住,这是一个低流量的网站。每天每页 30 次浏览量最高。相同的 IP,相同的用户代理在 4 分钟内 3 次让我相信它们是同一台机器上的同一个人多次触发计数器。这种情况发生在现在大约 12% 的案例中。我的想法是每个 page_id 有 1 行,而不是每个 pageview 有 1 行。一个月后,如果我在每个页面视图中使用一行,我的表中就会有数千行。你怎么看?
    • 我的重复没有同时发生。它们会在几秒到几分钟内发生。如果我确实按照您建议的方式设置了表格,我仍然需要检查相同的 page_id 和 ip 组合是否没有在我认为太接近的时间间隔内注册。我也不想让它只计算每个 IP 的一次综合浏览量。如果您明天或几个小时后回来,我希望它算作另一次页面浏览。我只是不想在同一个 5 分钟的“会话”中获得多次计数。
    • 感谢您的快速更新。你说得对,驱动空间很便宜。我主要担心数千行会减慢 mysql 的速度。我不确定这是否是一个有效的问题,因为我对 mysql 不太熟悉。你能详细说明一下时间戳吗?我不明白它如何确保我永远不会得到重复。重复是指同一 IP 在 5 分钟内多次查看同一页面。据我了解,它只会确保我不会在同一秒发生重复,但我的重复会在几分钟内发生。我错过了什么吗?
    【解决方案3】:

    我想我可能会找到解决会话问题的方法。实际上,我从会话切换到 cookie。

    我的很多网页都通过 iframe 获得浏览量。 iframe 导致 IE 浏览器出现问题。除非我添加 p3p 标头,否则 IE 无法从 iframe 中读取 cookie 数据。

    我添加了 p3p 标头,现在它似乎可以正常工作了。我厌倦了微软和他们的安全理念。我也不知道 p3p 是什么,但这就是它在 php 中的样子。

    header ( "p3p:CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");
    

    【讨论】:

      【解决方案4】:

      您正在寻找的是CASE 声明:http://dev.mysql.com/doc/refman/5.0/en/case-statement.html

      CASE 语句示例:

      SELECT name,
             (CASE WHEN is_happy THEN "Happy!"
              ELSE "sad." END) as happiness 
      FROM user_state;
      

      它们也可以用于UPDATEINSERT

      我怀疑你想看看 IE 的东西,而不是。过去我也遇到过类似的问题,最后我不得不使用 javascript 来消除点击次数。我不确定是 IE 用户双击东西还是 IE 很奇怪。

      【讨论】:

      • 感谢您的回复。我遇到了 CASE 声明文档,但我真的不明白如何应用它。你有任何关于如何在 php sql 查询中使用案例的教程或简单解释的例子吗?至于IE点击的东西,在这种情况下计数器代码是页面的一部分。用户不必点击任何东西来触发它,只需加载页面。在我的测试中,当您第一次加载页面时,它计为 1,但如果您刷新,它不会因为会话第一次处理该 page_id。我怀疑人们会连续 3 次关闭和打开浏览器!
      • 我上面添加的例子有帮助吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-26
      • 2014-02-05
      • 2014-10-18
      • 2020-07-21
      • 1970-01-01
      相关资源
      最近更新 更多