假设我有一堆包含大量记录的表,我想将其随机呈现给用户。我还希望用户能够来回分页,所以我必须坚持某种顺序,至少在一段时间内。
该应用程序基本上只是AJAX,它为已访问过的页面使用缓存,所以即使我总是提供随机结果,当用户尝试返回时,他将获取上一页,因为它将从本地缓存加载
问题是,如果我只返回随机结果,可能会有一些重复。每个页面包含6个结果,因此为了防止这种情况,我必须执行类似WHERE id NOT IN (1,2,3,4 ...)
之类的操作,我会将所有以前加载的ID放在其中。
该解决方案的巨大缺点是无法在服务器端缓存任何内容,因为每个用户都会请求不同的数据。
替代解决方案可能是创建另一列来排序记录,随机每次插入时间单位。这里的问题是,我需要将序列中的随机数设置为表中的每个记录,这将占用与记录一样多的查询。
如果有任何相关性,我正在使用Rails和MySQL。
答案 0 :(得分:7)
试试这个:
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 |
+------+
请注意,rand()函数具有种子值(123)。另请注意,如果重复最后三个查询,则每次都会得到相同的结果。
答案 1 :(得分:2)
我会执行以下操作(假设顺序数字主键):
答案 2 :(得分:2)
如果随机结果是“为每个人”而不是任何特定用户,那么你可以这样做:(这适用于Postgres,应该与其他人合作)
update mytable set sortorder = random() * 100000000;
select * from mytable order by sortorder, primarykeyid;
由于随机MAY可以重复,因此通过primarykeyid进行的二次排序可以使排序具有一定的稳定性。
然后,您可以根据需要刷新缓存来执行此操作。例如,给你的页面绝对过期,比方说,每分钟。然后每分钟重新更新排序顺序并正常提供页面。
如果您在刷新窗口中收到请求,那么,是的,您有可能让不同的页面获得相同的结果。你也会遇到问题,当他们“回来”时,他们可能无法获得他们之前的页面(自刷新以来)。
归结为随机数据的呈现背后的动机是什么,这将是多么有效。它还取决于数据量等。
但是如果这对你很重要的话,这是一种缓存友好的方法。它也是无状态的(不需要会话信息)。