【发布时间】:2017-04-19 21:21:35
【问题描述】:
我有一个array,我在其中取出了random 项目
[a, b, c, d ,...]
function getRandomItem(){
// return random item from array
}
我也有一个这样的 SQL 表:
category_id
random_item
然后我想将该项目添加到表中。对于每个category_id,我想要多行随机项,例如:
- 每个类别中没有重复的项目(项目 a 不能重复使用 category_id 1,但项目 a 可以在
category_id1 和category_id2 中) - 项目数将小于数组的长度。 (这并不是一直都是这样的要求)。
这里有一些虚构的代码可以做到这一点:
function persist(){
var a = giveRandomItem();
// $1 = a
return execute("INSERT INTO mytable (random_item) values ($1) ON CONFLICT DO NOTHING RETURNING *", a)
}
// usage
var persisted;
while(persisted === undefined){
persisted = persist();
}
问题在于它不是恒定的时间。我有可能连续 5 次点击 DB,因为该项目已经被持久化。
对于每个类别,我预计最多 5k 个项目,我的数组长度为 400 000。所以概率很低。
我还是想找到一种时间恒定的方法,或者至少有一个可以尝试多个值的sql命令,以进一步降低概率。
用例
我能想到的一个简单的用例是这样的(没用但是很简单):
用户会看到一个界面,他们可以在其中选择一个类别。然后他们可以按下一个按钮,向其中添加一个随机项目。 有多个用户,每个用户都单独行动。因此,用户 1 可以将随机项目添加到类别 1,而用户 2 同时将随机项目添加到类别 2
编辑
我最终做了这样的事情:
在应用程序级别:
shuffle(array);
function getRandomItem(seed, inc){
let index = (seed + inc) % array.length;
return array[index]
}
// usage:
let seed = item.category_id
let inc = category.item_count
这样我就没有重复了,因为我说项目的数量低于数组的长度。此外,这些项目似乎是随机的,因为类别的 id 被用作增量开始的种子。然而,这只是起点,因此它并不是真正随机的,但适用于我的用例。
【问题讨论】:
标签: sql postgresql rdbms