繁体   English   中英

什么是“改组”数据库记录表的最佳方法?

[英]What's the best way to “shuffle” a table of database records?

假设我有一堆包含大量记录的表,我想随机向用户呈现这些记录。 我还希望用户能够来回分页,所以我必须坚持某种顺序,至少在一段时间内。

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

问题是,如果我只返回随机结果,可能会有一些重复。 每个页面包含6个结果,所以为了防止这种情况,我必须做一些像WHERE id NOT IN (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)。 另请注意,如果重复最后三个查询,则每次都会得到相同的结果。

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

  1. 生成随机数并将其存储在用户的会话中
  2. 当用户翻阅数据时,查询总行数
  3. 使用会话中存储的数字作为种子,在每个请求上生成相同的“随机”ID顺序
  4. 通过ID页面,只检索与数据库中的那些ID匹配的记录。

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

update mytable set sortorder = random() * 100000000;

select * from mytable order by sortorder, primarykeyid;

由于随机MAY可以复制,因此通过primarykeyid进行的二级排序可以使排序具有一定的稳

然后,您可以根据需要刷新缓存来执行此操作。 例如,给你的页面绝对过期,比方说,每分钟。 然后每分钟重新更新排序顺序并正常提供页面。

如果您在刷新窗口中收到请求,那么,是的,您有可能让不同的页面获得相同的结果。 你也会遇到一个问题,当他们“回来”时,他们可能无法获得他们之前拥有的页面(因为它已经刷新)。

可归结为随机数据的呈现背后的动机是什么,它将如何运作。 它还取决于数据量等。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM