2011-06-16 57 views
9

我已经写了一个自定义论坛脚本使用PHP。我决定不使用phpbb和其他人,因为我希望100%的灵活性与我正在做的事情。自定义PHP论坛 - 显示新/未读帖子

我虽然打了一个问题:

如何显示用户如果一个职位是新/未读或不。

两种解决方案进入脑海:

1)饼干 2)数据库

我不想使用cookies,因为它们可以由用户和事物的Firefox的一侧被删除意味着他们自动删除。无论哪种方式,我不想使用cookie。

数据库引起了我一个问题,因为我似乎无法让我的头排序的数据库结构!我能想到的第一个解决方案是:

  • 当用户加载的论坛时,检查它们加载的论坛了
  • 检查所有的职位已经进行了自上次看论坛的最后一次
  • 在包含字段(user_id,post_id)的表中将这些值输入到数据库中。
  • 该值,然后从数据库中删除时,他们查看后

我想这个是它是一个庞大的数据库漏的问题。看起来效率不高。我确定在字段中有数组的方法,但我对数组并不是很擅长。

谁能给我一个很好的数据库设计的过程,以及有去与它的任何代码的指示?这让我疯狂,因为我无法想到一个对服务器来说很好并且高效的解决方案。

非常感谢您的帮助和帮助,

詹姆斯。

+0

只需添加一列即可将布尔值添加到帖子表中,如果已查看,则将其设置为true,如果尚未查看,则设为false – 2011-06-16 16:07:47

+1

您可以比较现有电路板软件如何执行此操作。例如PHPBB或MyBB或其他各种代码可以免费使用。然后选择适合您的需求。 – hakre 2011-06-16 16:08:21

+0

我毫不犹豫地发表了这个建议,但我正在考虑和你一样做,然后我落在了Vanilla论坛上,这个论坛提供的内容非常精简,并且可以随时随地插入你需要的各种位。就像哈克雷所暗示的那样,即使你不采用它,你也可能会比检查它们是如何做的更糟糕。 – Cups 2011-06-16 16:42:23

回答

11

这是某种一个很好的问题,我以前从来没有经历过这个,所以我只能建议你的想法中,我不知道它的正确性的保证。

我的想法主要是:

  1. 创建一个新的领域,被称为is_new主题表格内。该字段包含字符串形式的值列表,遵循特定模式。例如:5|6|12|110|2|45。介于|之间的每个值表示已阅读主题的用户ID。

  2. 用户每次跳进了一个论坛,同时获取返回的主题列表,你会检查每个主题由用户读取,通过简单:

    • 使用爆炸字符串中is_newexplode('|', $row['is_new']);
    • 现在你有一个数组包含值,只需要检查in_array($user['id'], $list_of_ids);
  3. 如果false,纪念主题unread,否则标记为read,并将该用户的ID更新到is_new列表中。

这种做法似乎比你原来的做法少“痛苦”,因为它只比普通的进一步检查,并且同时为你获取的主题列表。如果你有大量的用户,我认为它会影响更多。

注意:因为is_new包含多个值,所以您不必担心规范化问题,因为您只使用它来检查和更新,不需要进行选择。

此外,用户也可检查的主题是新的或不使用的时间比较。例如,如果一个话题持续4周,而用户没有阅读,那么即使它没有被阅读,它也会返回老的(这是否有道理?就像报纸一样)。我认为你将能够做到这一点,确实很容易。

这种方法特别是相当多的论坛软件应用,因为它是快速和更有意义。请记住,浏览器最初支持您确定已读/未读主题,即如果访问该主题的超链接的颜色将被更改。现在又回到了Cookies解决方案。我不会担心用户删除他们的cookies。这种情况很少发生,用户不会因为read主题在删除Cookie后将其转为unread而死亡。

相当开放式的话题,不是吗?希望这有助于(:

+1

@BeingSimpler,加一!很好的答案! – hypervisor666 2011-06-16 18:07:26

+1

这当然是一种有效的方法,但is_new专栏让我感觉有点肮脏。虽然你的规范化观点在技术上是正确的,但仍然有一个很好的理由将此信息分解到另一个表中:与JOIN相比,执行字符串爆炸,数组遍历和可能的数组更新非常慢。关系数据库的构建是为了快速有效地关联这种类型的信息,为什么不利用它呢? – 2011-06-17 21:43:12

+0

贾斯汀,好点的(:但是我仍然认为在这种情况下,它不会影响太大,因为更新新的ID就像追加一个新的字符串到当前字符串,像“UPDATE主题集is_new = CONCAT(is_new,'| $ id')“。正如我所说,这个字段作为一个独立的存储来匹配值,它不需要与任何其他字段相关,也不需要任何特定的选择。你的方法是正确的,它甚至听起来真实的我,但它是从我的思想和方法不同。煤矿发生可能是两行代码,并答复不会减慢那么多比使用原始RDB apporach。 – 2011-06-17 23:58:35

0

会话将存储这个的好地方。我想你只想存储用户查看的最后“n”个线程的数据,或者仅存储最后“n”天的线程的数据。

正如有人在它的值得看的一些现有论坛在那里评论的人提出,看看他们是如何实现这一点。

虽然我认为这是一个很好的学习机会,在构建它的效率而言写自己的论坛软件自己,我认为你正在重新发明轮子一些。

+0

会话的问题是我不得不使用数组来做到这一点吗?那么,如果该人关闭浏览器会发生什么?他们仍然会拥有以前没有阅读过的新帖子,即使他们是新手,他们也不会再被显示为“新”。 使用数据库的好处是,即使关闭浏览器,帖子始终保持为“新”,因为在读取该值之前,该值保持“未读”状态。 我同意我“重新发明轮子”可以这么说,但我厌倦了试图修改其他人的编码以使其适用于我。它只是不工作.. – James 2011-06-16 16:18:25

+0

不能使用数组将会限制您构建功能的能力。我真的建议投资一些时间来了解它。有一堆很好的教程,只需搜索“PHP阵列”Google – 2011-06-16 16:21:14

+0

感谢您的建议。关于我在会议上提出的观点,你会对此提出什么建议?如果他们通过查看新帖子来关闭浏览器,如果他们稍后再回来会发生什么情况? 我将尝试加载phpbb论坛代码,看看他们如何显示新帖子。我不确定是否有可能找到它..但我会尝试! :) 如果你在数据库方面的任何想法,一定要让我知道:)谢谢 – James 2011-06-16 16:24:02

1

嗯,好问题

我会折腾我的两分钱在我将如何处理这个问题,它可能不是最有效的解决方案,但在这里有云:

我将使用数据库来解决这个问题,如果可能的话,在数据库中创建一个附加到特定用户的字段,在该字段内(或者列或表,如果您愿意的话)可以存储文章ID的“已查看”文章列表

呈现给用户的页面时,找回自己的“观察”的文章列表,所有的物品ID的可用的列表。

遍历你的文章/论坛/主题结果集,看看是否ID匹配任何的“看”的ID。对于没有相应的“查看”匹配的每篇文章/论坛/主题条目,则对于该用户而言,它将是“新”文章。

这是处理器/数据库/网络密集型的,需要每个页面加载时间,其中包含引用的文章中查找到数据库中。尽管有一些聪明的查询设计,我认为你可以将这种操作几乎完全卸载到数据库。

另一个使用数据库的潜在解决方案是,当用户首次登录网站时,您可以在第一个加载点获取已读文章/论坛列表,并将其添加到cookie或会话中,这样您只需在第一次加载时就为该列表命中数据库,并将其存储在session/cookie/hidden字段中,以便在随后的请求中,您只需转到该cookie/session/hidden字段而不是执行Db每次用户查看包含文章/论坛/主题列表的页面时都要查找。每次用户点击一个链接时,捕获并将其存储在数据库中,并将该文章/论坛ID存储在cookie/session/hidden字段中。再一次,也许不是最有效的方法,但有一些好的老式消费,我相信你会占上风。 :)

祝你好运!

^h

5

很多大论坛软件的使用跟踪表跟上谁读过什么,像这样(严重简化):

CREATE TABLE topic_tracking (
    user_id INT NOT NULL, 
    topic_id INT NOT NULL, 
    last_visit DATETIME NOT NULL, 
    PRIMARY KEY (user_id, topic_id) 
) 

然后,您使用连接上此表格检查您显示的帖子是否被读取。既然你会分页你的线程,这应该会产生相对较少的附加查询(取决于你每页显示多少篇文章)。

当用户访问该线程时,使用其访问的时间戳更新此跟踪表。然后,当显示您的线索链接时,请检查此表以查看他们的last_visit是否早于线索中的最后一个帖子。这也可以让你显示“更新”的线程,而不仅仅是“新”的线程。

0

我的做法是,以节省每一个主题特定的用户数据库中已经看到的最后一个职位编号:

user_id topic_id post_id 
1   2   3 

所以,在这里,你知道,用户1对第二个专题走访后第三,但根本没有看第一个话题。

要检查用户是否有新/未读主题,您可以首先检查该用户不在该表中的topic_id。要检查已知主题是否有新消息,可以将post_id与每个主题的最后一个post_id进行比较。如果不相等,则会有新消息。