Mysql 什么';“这是最好的方式”;洗牌;数据库记录表?
假设我有一个包含大量记录的表,我想随机向用户展示这些记录。我还希望用户能够前后分页,所以我必须保持某种顺序,至少在一段时间内 这个应用程序基本上只是AJAX,它对已经访问过的页面使用缓存,所以即使我总是提供随机结果,当用户试图返回时,他也会得到上一个页面,因为它将从本地缓存加载 问题是,如果我只返回随机结果,可能会有一些重复的结果。每个页面包含6个结果,因此为了防止出现这种情况,我必须执行类似于Mysql 什么';“这是最好的方式”;洗牌;数据库记录表?,mysql,ruby-on-rails,database,random,Mysql,Ruby On Rails,Database,Random,假设我有一个包含大量记录的表,我想随机向用户展示这些记录。我还希望用户能够前后分页,所以我必须保持某种顺序,至少在一段时间内 这个应用程序基本上只是AJAX,它对已经访问过的页面使用缓存,所以即使我总是提供随机结果,当用户试图返回时,他也会得到上一个页面,因为它将从本地缓存加载 问题是,如果我只返回随机结果,可能会有一些重复的结果。每个页面包含6个结果,因此为了防止出现这种情况,我必须执行类似于的操作,其中id不在(1,2,3,4…)中,我将所有先前加载的id放在其中 该解决方案的巨大缺点是不可
的操作,其中id不在(1,2,3,4…)
中,我将所有先前加载的id放在其中
该解决方案的巨大缺点是不可能在服务器端缓存任何内容,因为每个用户都会请求不同的数据
另一种解决方案可能是创建另一列对记录进行排序,并在此处每插入一个时间单位对其进行洗牌。这里的问题是,我需要将随机数从一个序列中设置到表中的每一条记录,这将需要和记录一样多的查询
如果有关联的话,我正在使用Rails和MySQL。我将执行以下操作(假设使用顺序的数字主键):
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)。另外请注意,如果您重复最后三次查询,每次都会得到相同的结果。如果随机结果是“针对所有人”而不是针对任何特定用户,那么您可以这样做:(这是针对Postgres的,应该与其他人一起使用)
由于random可能重复,因此primarykeyid的二级排序使排序具有一定的稳定性
然后,您可以随时刷新缓存来执行此操作。例如,给页面一个绝对过期时间,比如说,每分钟。然后,每分钟你都会重新更新排序顺序,并正常地将页面送达
如果您在刷新窗口中收到请求,那么,是的,您有机会让不同的页面获得相同的结果。您还将遇到这样的问题:当他们点击“back”时,他们很可能无法获得以前的页面(因为页面刷新了)
从某种程度上讲,随机数据呈现背后的动机是什么,以及它的工作效果如何。它还取决于数据量等
但如果这对你很重要的话,这是一种缓存友好的方法。它也是无状态的(不需要会话信息)。作为用户在随机数据中分页对我来说没有多大意义。如果你把它称为“6篇随机帖子”,并且仅仅与可能的重复文章一起生活,那么它似乎就是你所要求的,不需要任何额外的努力。那么对答案的回应如何?我很想知道建议的解决方案是否适合您。ORDER BY RAND()是最糟糕的,因为它需要mySQL复制整个表,在每行添加一个RAND()值,最后进行排序。在6行表上没有问题,但行数越多效率就越低。您的mySQL服务器可能会变得更慢、过载。
update mytable set sortorder = random() * 100000000;
select * from mytable order by sortorder, primarykeyid;