每个帖子都有很多标签。 (非常类似于SO)。我想要20个随机物品,不重复。
我知道我可以使用Tags.all.rand
(并重复10次)但是,这并不能保证唯一性。
我知道我可以使用SQL查询,但由于我的开发环境使用sqlite作为生产中的db和MySQL,ORDER by RAND
将不适用于两者。
除了有两个不同的查询(Dev& Prod),我还能做些什么?
由于
答案 0 :(得分:2)
为什么要使用两个不同的数据库进行开发和生产?这可能会导致进一步的问题。以我们最近发生的事情为例,我们的一个开发人员使用了MySQL,并使用了一种特殊的MySQL-only LIKE语法,这种语法在我们的PostgreSQL生产数据库中不起作用。
故事的故事:如果你在开发,测试和/或制作中使用不同的东西:你做错了。
下一步:要获取MySQL中的随机项,您可以执行:Tag.all(:order => "RAND()", :limit => 10)
。
答案 1 :(得分:2)
Ryan的答案是这样做的,但附带了一个问题。如果您的数据集非常大,则:order => “RAND()”是不切实际的(查询运行速度非常慢)。有两种替代方法:首先获取项目的所有ID,随机选择20然后获取这些行,或者获取数据库中的项目数,选择一个具有随机偏移的项目,然后重复(首先选择偏移量)保证没有重复。)
在SQL Antipatterns书中阅读更多相关内容,本章为免费赠送。
BTW:如果使用Ruby 1.8+或Rails 2.3+(我相信),有一种方法Array#sample可以让你选择n个元素而不重复,就像你原来的方法一样。答案 2 :(得分:2)
您可以使用以下方法选择20个标签的随机样本:
Tag.all.sort_by {rand}[0..19]
(感谢这个简单解决方案的chubas!)
这样做的缺点是它对大型数据集的效率低下。您可以通过仅选择ID来改善这一点:
Tag.all(:select => :id).map(&:id).sort_by{rand}[0..19]