我有一个行的数据集,每个行的“赔率”都在1到100之间。我希望以最有效的方式来做。几率不一定等于100。
我有一些想法。
a)
选择整个数据集,然后将所有赔率相加,生成一个介于1和该数字之间的随机数。然后循环数据集,从数字中减去赔率,直到它为0。
我希望将对数据库的影响降到最低,所以我考虑是否只能选择所需的行。
b)
SELECT * FROM table WHERE (100*RAND()) < odds
我考虑过
LIMIT 0,1
但如果项目具有相同的概率,则只返回其中一个
或者取整个数据集,从中随机选取一个…但是当它变成随机的有赔率,然后是随机的无赔率时,赔率会受到影响,因此赔率会倾向于更高的赔率(甚至更高)。
我想我可以
order by odds
asc然后获取整个数据集,然后使用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时被触发器更新。
显然,在更新开始/结束时有一些麻烦。这也不算太糟
桌子上的东西很稳定
或者插入在某种程度上是自然有序的,这样每一行就从原来的最高点开始。