Php 有效地从MySQL中选择状态更新源的项目,同时考虑可能的垃圾邮件

Php 有效地从MySQL中选择状态更新源的项目,同时考虑可能的垃圾邮件,php,mysql,algorithm,sorting,memcached,Php,Mysql,Algorithm,Sorting,Memcached,我正在创建一个“状态更新”提要,用户可以在其中发布其他用户可以查看的一般消息(想想facebook、twitter推文等中的状态更新)。首先,在创建帖子并将其保存到数据库时,会为每个帖子分配一个排名分数。该排名分数与时间衰减函数相结合,用于在提要生成并呈现给用户时为每个帖子分配“真实排名”。真正的排名是项目最终的排序方式 当引入一种打击“垃圾邮件”的策略(我们不希望用户能够非常迅速地发帖并占据提要的首位)时,就出现了复杂性。策略是跟踪用户在(比如)最后一个小时内发布的次数。对于在最后一小时内添加

我正在创建一个“状态更新”提要,用户可以在其中发布其他用户可以查看的一般消息(想想facebook、twitter推文等中的状态更新)。首先,在创建帖子并将其保存到数据库时,会为每个帖子分配一个排名分数。该排名分数与时间衰减函数相结合,用于在提要生成并呈现给用户时为每个帖子分配“真实排名”。真正的排名是项目最终的排序方式

当引入一种打击“垃圾邮件”的策略(我们不希望用户能够非常迅速地发帖并占据提要的首位)时,就出现了复杂性。策略是跟踪用户在(比如)最后一个小时内发布的次数。对于在最后一小时内添加的每个后续帖子,分配的排名分数将受到处罚。用户在最后一小时内发布的帖子越多,排名分数惩罚越大。这里的想法是将潜在的垃圾邮件进一步推下提要,同时仍然给它一个显示的机会

下面说明了如果我们不考虑垃圾邮件,那么在同一用户快速发布四个项目后,如何对提要进行排序

Item 1: Posted 1 min ago. True Rank = 0.99. user_id = 666.
Item 2: Posted 2 min ago. True Rank = 0.98. user_id = 666. SPAM.
Item 3: Posted 3 min ago. True Rank = 0.97. user_id = 666. SPAM.
Item 4: Posted 4 min ago. True Rank = 0.96. user_id = 666. SPAM.
Item 5: Posted 5 min ago. True Rank = 0.95. user_id = 100.
Item 6: Posted 6 min ago. True Rank = 0.94. user_id = 100.
以下是我们想要的。请注意,按用户_id=666发布的文章将在第一篇文章之后从提要中删除

Item 1: Posted 1 min ago. True Rank = 0.99. user_id = 666.
Item 5: Posted 5 min ago. True Rank = 0.95. user_id = 100.
Item 6: Posted 6 min ago. True Rank = 0.94. user_id = 100.
Item 2: Posted 2 min ago. True Rank = 0.88. user_id = 666. SPAM.
Item 3: Posted 3 min ago. True Rank = 0.77. user_id = 666. SPAM.
Item 4: Posted 4 min ago. True Rank = 0.66. user_id = 666. SPAM.
问题 我有一个这样做的策略。如上所述,我正在跟踪每个用户每小时的帖子数量,并在必要时从排名分数中扣除。这没问题

每当我们为用户准备提要时,在考虑如何有效地从数据库中选择项时,就会出现问题。这是关于性能的。比如说,我希望一次选择1000个提要项(最初选择1000个,如果用户请求更多,则每次提取1000个)。但如果前1000个项目全部或大部分是垃圾邮件呢?选择所有项目,然后准备提要在技术上是可行的,但系统中的项目数量可能非常大

我正在努力创建一种算法,该算法可以为提要选择项目,而无需一次提取大量内容,同时还可以让每个提要项目都有机会显示在提要上,即使其排名非常低

像让用户每小时只发布n个项目这样的人工解决方案是不可取的

值得一提的是,我使用的工具是MySQL、Memcached和PHP


提前感谢您的帮助。

我认为使读取真正高效的方法是确定何时在插入时排除帖子(可能有一个单独的通知表,并使用一些速率限制,例如漏桶算法,以确定排除哪些帖子)

要对目前的数据做一些接近您想要做的事情,您可以这样做

它的意思是“在每N篇帖子中,每个用户只允许显示一篇帖子”。您必须调整N值(本例中为5)以获得数据速率,但它与数据配合得相当好


就功能而言,更好的版本可能是(如果您存储帖子的时间戳)根据帖子的时间进行划分,以及现在的时间和帖子的时间之间的差异。我认为这样做的速度会慢一些,因为您将分组到一个派生列上。

一开始不发布垃圾邮件不是更好吗?让垃圾邮件大放异彩只会鼓励更多的垃圾邮件。如果这里对垃圾邮件的定义有误导性,请道歉。应该更准确地称之为“潜在垃圾邮件”。我们仍然希望显示所有项目,因为频繁发布并不一定是坏事(我们将为用户提供报告功能,以提醒我们真正恶意的帖子)。在任何情况下,我们都想给所有的帖子一个沉浮的机会(也许除非某个物品的排名非常低)。谢谢你的建议。我现在正在研究一个解决方案,并牢记其中一个原则。也就是说,在插入时预先执行更多逻辑。一旦有了更多的细节,我会回来更新。