ruby-on-rails 对数据库记录表进行“ Shuffle ”的最佳方法是什么?

rbl8hiat  于 5个月前  发布在  Ruby
关注(0)|答案(4)|浏览(67)

假设我有一个包含一堆记录的表,我想随机地将它们呈现给用户,我还希望用户能够来回分页,所以我必须保持某种顺序,至少在一段时间内。
应用程序基本上只有AJAX,它使用缓存已经访问过的页面,所以即使我总是提供随机结果,当用户试图返回时,他将获得前一页,因为它将从本地缓存加载。
问题是,如果我只返回随机结果,可能会有一些重复的结果。每个页面包含6个结果,所以为了防止这种情况,我必须做一些类似WHERE id NOT IN (1,2,3,4 ...)的事情,我会把所有以前加载的ID放在那里。
该解决方案的巨大缺点是,它不可能在服务器端缓存任何内容,因为每个用户都会请求不同的数据。
另一种解决方案可能是创建另一个列来对记录进行排序,并在每个 *insert time unit here**对其进行 shuffle。这里的问题是,我需要为表中的每个记录设置随机数,这将需要与记录数量一样多的查询。
我使用Rails和MySQL,如果这是任何相关的。

nfeuvbwi

nfeuvbwi1#

试试这个:

mysql> create table t (i int);
mysql> insert into t values (1),(2),(3),(4),(5),(6);
mysql> select * from t order by rand(123) limit 2 offset 0;
+------+
| i    |
+------+
|    6 | 
|    4 | 
+------+
mysql> select * from t order by rand(123) limit 2 offset 2;
+------+
| i    |
+------+
|    2 | 
|    3 | 
+------+
mysql> select * from t order by rand(123) limit 2 offset 4;
+------+
| i    |
+------+
|    5 | 
|    1 | 
+------+

字符串
注意兰德()函数有一个种子值(123),如果你重复最后三个查询,你每次都会得到相同的结果。

9vw9lbht

9vw9lbht2#

如果随机结果是“为每个人”,而不是任何特定的用户,那么你可以这样做:(这是为Postgres,应该与其他人一起工作)

update mytable set sortorder = random() * 100000000;

select * from mytable order by sortorder, primarykeyid;

字符串
由于随机可能会重复,所以通过primarykeyid进行的二级排序给了排序一些稳定性。
然后,您可以根据需要随时刷新缓存。例如,给予页面绝对过期时间,比如每分钟。然后每分钟重新更新排序顺序,并正常提供页面。
如果你在刷新窗口中收到请求,那么,是的,你有机会让不同的页面得到相同的结果。你也会遇到这样的问题,当他们点击“返回”时,他们可能不会得到他们之前的页面(因为它刷新了)。
某种程度上可以归结为随机数据呈现背后的动机是什么,以及这将如何工作。这也取决于数据量等。
但这是一种缓存友好的方式来实现这一点,如果这对你很重要的话。它也是无状态的(不需要会话信息)。

li9yvcax

li9yvcax3#

我将执行以下操作(假设一个顺序的数字主键):
1.生成一个随机数并将其存储在用户的会话中
1.当用户逐页浏览数据时,查询总行数
1.使用存储在会话中的数字作为种子,在每个请求上生成相同的“随机”顺序的ID
1.遍历这些id,只从数据库中检索与这些id匹配的记录。

dba5bblo

dba5bblo4#

SET @rownum:=(SELECT_BLOG(1)FROM tbl_BLOG_mapping);
SET @row:=(SELECT CEIL((兰德()* @rownum);
SELECT @row;
SELECT * FROM tbl_mapping WHERE id = @row;

相关问题