【问题标题】:Creating a Recently Viewed list, MySQL or Redis创建最近查看列表、MySQL 或 Redis
【发布时间】:2012-10-07 05:49:06
【问题描述】:

我有一个用户浏览搜索结果的网站。记住用户查看了哪些结果并将它们标记为Viewed 将很有用。

问题:要实现这样的Recently Viewed列表功能,推荐的方法是什么?

  1. 使用像 MySQL 这样的 RDBMS。每次用户单击链接时,向服务器发出 AJAX 调用以将新行插入到表 views 中,其中列 iduser_iditem_idtimestamp。在显示任何搜索结果之前,将根据表 views 检查每个项目的 id,以确定该列表是否将标记为 viewed(如果这有帮助,我的 PHP 框架 Laravel 可以使用数据库或 redis 作为会话驱动程序而不是使用 cookie)

  2. 使用像 Redis 这样的内存数据存储。我对redis/memcached没有经验,想到用这个的原因是因为大量写入viewed表,而读取主要是通过主键选择的(Redis中有索引的概念吗? ?)

感谢您提出的任何建议和意见,尤其是那些对这两种技术有经验的人。

【问题讨论】:

  • 您是否打算在当前浏览会话之后保留此内容?
  • 是的,它应该持续到 2 周后,在那里可以修剪 views 表。观看历史记录仅对注册用户开放。
  • 不清楚为什么这被标记为postgresql

标签: php mysql memcached redis


【解决方案1】:

在您提到的技术之间进行选择时没有经验法则,至少在没有更全面的上下文(例如服务器负载、访问量、数据量、数据库写入与读取比率等)的情况下,因为它们都没有比另一个“更好”,它们只是不同的工具。

每个页面查看一个 MySQL INSERT 不太可能对性能造成哪怕是最轻微的影响,除非您指望有数以万计的并发(即同时访问该站点,在完全相同的时间)用户。我建议:专注于 MySQL,因为这似乎是你最了解的,因为你会更快地移动,并且更早地完成你正在做的任何事情。如果它真的最终成为瓶颈,您以后总是可以切换到不同的方法。

话虽这么说:如果您喜欢冒险并且时间不是问题:

  • redis 非常适合您尝试做的事情。 基本上,每个用户都有一个排序集,包含 itemids 以时间戳作为分数。这很容易检索(名称 用户 ID 后面的每个键,例如user:$userid:recentviews), 容易 分页(ZREVRANGE 将为您提供最新的 x 视图)并且很容易 过期(ZREMRANGEBYRANK 范围在 0 和时间戳之间 now-30 days 删除所有超过 30 天的条目,例如) 并且与其 MySQL 相比应该具有相对的内存效率 反部分。如果现在这一切听起来像是胡言乱语,请不要担心,一旦您学习了 redis,这一切实际上都非常直观。

  • Memcached 被严格设计为缓存而不是数据存储,因此它的数据类型有点不灵活(您很可能必须存储 json 字符串并对其进行解析/字符串化随你去,这增加了不便,不能部分编辑列表而不先完全检索它)并且与redis相反,它不会将数据持久化到磁盘,所以我个人不推荐它用于您最近的视图系统.如果您最近的视图数据不稳定且很小,它可能适合,但我不认为 memcached 比 redis 快得多。

如果你有时间,我建议你搜索和阅读更多关于 redis 和 memcached 的内容,直到你对它们是什么以及如何使用它们有一个很好的了解;只有这样,您才能做出明智的决定。但正如我之前提到的,请记住,除非您的需求非常特殊,否则 MySQL 可能会很好地完成这项工作而不会出现性能问题。

【讨论】:

    【解决方案2】:

    我有类似的东西,但它应该适用于你想要得到的东西。您不能通过在每个页面中包含一个文件来存储他们访问的页面。如果您有一个 session.php 文件或包含在每个页面上的类似文件,您可以将以下代码放入其中

    $insert = mysql_query("INSERT INTO views VALUES
    ('$user_id','$itemid','$timestamp')");
    

    (id 应该在数据库中自动递增)

    这将插入页面及其当前所在的 id。您将需要在该页面中定义页面 ID。对我来说这很容易,因为我使用了 profile.php?id=1 之类的东西。然后在哪里显示搜索结果..

    $checkid = mysql_query("SELECT * FROM views WHERE user_id='$userid' & itemid='$itemid');
    $views = mysql_num_rows($checkid);
    
    if($views > 1){
    $viewed = "false";
    }else{
    $viewed = "true";
    }
    

    然后在您的页面上显示结果,您可能会有类似的结果 如果($查看=“真”){ echo "您已浏览此页面 $views time(s)"; }elseif($viewed = "false"){ echo "您还没有浏览过这个页面"; }

    如果你遇到了一些没有意义的事情,请告诉我,我的睡眠时间不足!哈哈(我也不是 PHP 高手)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多