我有一个行的数据集,每个行的“赔率”都在1到100之间。我希望以最有效的方式来做。几率不一定等于100。
我有一些想法。
a)
选择整个数据集,然后将所有赔率相加,生成一个介于1和该数字之间的随机数。然后循环数据集,从数字中减去赔率,直到它为0。
我希望将对数据库的影响降到最低,所以我考虑是否只能选择所需的行。
b)

SELECT * FROM table WHERE (100*RAND()) < odds

我考虑过LIMIT 0,1
但如果项目具有相同的概率,则只返回其中一个
或者取整个数据集,从中随机选取一个…但是当它变成随机的有赔率,然后是随机的无赔率时,赔率会受到影响,因此赔率会倾向于更高的赔率(甚至更高)。
我想我可以order by oddsasc然后获取整个数据集,然后使用php从行中随机抽取一个与第一条记录(最低)的几率相同的值。
似乎是个笨拙的解决方案。
有没有更好的解决方案?如果不是以上哪一个最好?

最佳答案

做一些前期工作,在表中添加一些有助于选择的列。例如,假设您有这些行

 X  2
 Y  3
 Z  1

我们加上一些累积值
 Key Odds Start  End
 X    2     0     1      // range 0->1, 2 values == odds
 Y    3     2     4      // range 2->4, 3 values == odds
 Z    1     5     5      // range 5->5, 1 value == odds

开始和结束选择如下。第一行的开头是零。后续行的起始行比前一行的结束行多一个。结束是(开始+赔率-1)。
现在选择一个0到max范围内的随机数r(结束)
Select * from T where R >= T.Start and R <= T.End

如果数据库足够聪明,我们可以使用
 Select * from T where R >= T.Start and R <= (T.Start + T.Odds - 1)

我推测,有一个带有索引的结束列可能会带来更好的性能。另外,max(end)可能被藏在某个地方,并在ncessary时被触发器更新。
显然,在更新开始/结束时有一些麻烦。这也不算太糟
桌子上的东西很稳定
或者插入在某种程度上是自然有序的,这样每一行就从原来的最高点开始。

07-24 09:31