2011-01-05 140 views
4

说我有一个表了一系列的记录,我想随机存在给用户。我还希望用户能够来回分页,所以我必须坚持某种顺序,至少在一段时间内。什么是“洗牌”数据库记录表的最佳方式?

该应用程序基本上只有AJAX,并且它对已经访问过的页面使用缓存,所以即使我总是提供随机结果,当用户尝试返回时,他也会得到前一页,因为它会从本地加载缓存。

的问题是,如果我只返回随机的结果,可能有一些重复。每个页面都包含6个结果,所以要避免这种情况,我不得不这样做WHERE id NOT IN (1,2,3,4 ...),我会把所有的以前加载的ID。

该溶液的巨大缺点是,它不可能缓存在服务器端任何东西,因为每个用户将请求不同的数据。

替代的解决方案可能是订购的记录中创建另一列,并洗牌它的每插入时间单位在这里。这里的问题是,我需要为表中的每条记录设置一个序列中的随机数,这会占用与记录一样多的查询。

我使用Rails和MySQL的,如果这是任何意义的。

+1

作为用户的随机数据分页对我来说并没有多大意义。如果你称之为“6个随机帖子!”并只是与可能的重复生活在一起,似乎它将主要是你所要求的零工作。 – jdl 2011-01-05 23:46:44

+0

那么如何回答答案?我很想知道是否有任何解决方案建议适用于您。 – noodl 2011-01-11 11:44:45

回答

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)。另请注意,如果您重复最后三个查询,则每次都会得到相同的结果。

+0

ORDER BY RAND()是最糟糕的,因为它需要mySQL复制整个表格,为每行添加一个RAND()值并最终进行排序。 6行表格没有问题,但行数更多时效率非常低。预计你的mySQL服务器变得越来越慢并且超载。 – Sebastian 2015-02-11 09:25:00

2

我会做以下(假设顺序,数字主键):

  1. 生成一个随机数,并将其存储在用户的会话
  2. 当通过数据的用户的页面,请查询总行数
  3. 使用存储在会话中的号码作为种子,以在每个请求上生成相同的“随机”ids顺序
  4. Page通过ids并仅检索与数据库中的这些id匹配的记录。
1

如果随机结果是“大家”,而不是任何特定的用户,那么你可以做这样的事情:(这是Postgres的,应与他人合作)

update mytable set sortorder = random() * 100000000; 

select * from mytable order by sortorder, primarykeyid; 

由于随机可重复,通过primarykeyid进行二次排序使得排序具有一定的稳定性。

如要刷新缓存然后你可以做到这一点经常。例如,给你一个页面,比如说每分钟一次绝对过期。然后每分钟重新排列排序顺序并正常提供页面。

如果您在整个刷新窗口中收到请求,那么,是的,您有机会让不同的页面获得相同的结果。您也将有他们击中时的问题,“后退”,他们很可能无法获得页面之前,他们有(因为它刷新)。

种类归结为随机数据呈现背后的动机是什么,它会如何工作。它也取决于数据量等。

但是,如果这对你很重要,这是一种缓存友好的方法。它也是无状态的(不需要会话信息)。

相关问题