0

我正在使用 MySQL 5.5.8 版。

可以说我有这样的表,条目,结构:

entry_id int PK
member_id FK

每个成员可以有多个条目。我想随机获取其中的 10 个,但我需要以一种允许被选中的几率随着成员拥有的条目数量而增加的方式获取它们。我知道我可以这样做:

SELECT member_id
FROM entries
GROUP BY member_id
ORDER BY RAND()
LIMIT 10 

但我不确定这是否会达到我想要的效果。MySQL 会将记录分组然后选择 10 吗?如果是这样,那么每个成员都有相同的机会被选中,这不是我想要的。我进行了一些测试和搜索,但无法得出明确的答案。有谁知道这是否会做我想做的事,还是我必须以不同的方式做事?任何帮助,将不胜感激。非常感谢!

4

1 回答 1

1

LIMIT 10将在(在这种情况下)随机顺序中选择 10 条记录。这确实是在分组之后。

也许你可以ORDER BY RAND() / count(*)。这样,对于有更多问题的用户来说,这个数字可能会更小,因此他们更有可能进入前 10 名。

[编辑]

顺便说一句,似乎随着时间的推移(随着数据的增长)ORDER BY RAND()变得更慢。有几种方法可以解决这个问题。Mediawiki(维基百科背后的软件)有一个有趣的方法:它为每个页面生成一个随机数,因此当您选择“随机页面”时,它会生成一个介于 0 和 1 之间的随机数并选择最接近该数字的页面:

WHERE number > {randomNumber} ORDER BY number LIMIT 1` 

这样就不必为每个查询生成该临时表。如果数据增长,您将需要定期重新生成数字,并且必须确保均匀生成数字。这很容易:对于新记录,您只需生成一个随机数。定期更新整个列表:查询所有记录。然后,为该顺序中的每条记录分配一个介于 0 和 1 之间的数字,但以递增的数字递增1 / recordCount。这样,记录是均匀分布的,每条记录的查找变化都是相同的。

你也可以用那个方法。从长远来看,这将使您的查询更快,并且您可以使分布更智能:1)您可以使用“totalEntryCount”而不是使用“memberCount”。1 / 'memberCount'2)您可以使用 ,而不是增加entryCountForMember / totalEntryCount。这样一来,拥有更多条目的成员之前的差距会更大,因此他们匹配随机数的机会也会更大。例如,您的成员可能如下所示:

name  entries   number  delta
bob        10     0.1    0.10
john        1     0.11   0.01
jim         5     0.16   0.05
fred       84     1      0.84

当然,增量不会保存,但它会显示添加的数字。在 Mediawiki 示例中,此增量对于每个页面都是相同的,但在您的情况下,它可能取决于条目数。现在你看,bob 和 john 之间只有很小的差距,所以你在 0 和 bob 之间选择一个随机数的机会是在 bob 和 john 之间选择一个随机数的十倍。所以,挑选鲍勃的机会是挑选约翰的十倍。

您将需要一个(cron)作业来定期重新分配数字,因为您不想在每次修改时都这样做,但是对于您正在处理的数据类型,它不必是实时的,如果您有很多成员和许多条目,它会使您的查询更快。

于 2012-09-29T22:25:42.410 回答