Mysql 什么';“这是最好的方式”;洗牌;数据库记录表?

Mysql 什么';“这是最好的方式”;洗牌;数据库记录表?,mysql,ruby-on-rails,database,random,Mysql,Ruby On Rails,Database,Random,假设我有一个包含大量记录的表,我想随机向用户展示这些记录。我还希望用户能够前后分页,所以我必须保持某种顺序,至少在一段时间内 这个应用程序基本上只是AJAX,它对已经访问过的页面使用缓存,所以即使我总是提供随机结果,当用户试图返回时,他也会得到上一个页面,因为它将从本地缓存加载 问题是,如果我只返回随机结果,可能会有一些重复的结果。每个页面包含6个结果,因此为了防止出现这种情况,我必须执行类似于的操作,其中id不在(1,2,3,4…)中,我将所有先前加载的id放在其中 该解决方案的巨大缺点是不可

假设我有一个包含大量记录的表,我想随机向用户展示这些记录。我还希望用户能够前后分页,所以我必须保持某种顺序,至少在一段时间内

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

问题是,如果我只返回随机结果,可能会有一些重复的结果。每个页面包含6个结果,因此为了防止出现这种情况,我必须执行类似于
的操作,其中id不在(1,2,3,4…)
中,我将所有先前加载的id放在其中

该解决方案的巨大缺点是不可能在服务器端缓存任何内容,因为每个用户都会请求不同的数据

另一种解决方案可能是创建另一列对记录进行排序,并在此处每插入一个时间单位对其进行洗牌。这里的问题是,我需要将随机数从一个序列中设置到表中的每一条记录,这将需要和记录一样多的查询

如果有关联的话,我正在使用Rails和MySQL。

我将执行以下操作(假设使用顺序的数字主键):

  • 生成一个随机数并将其存储在用户会话中
  • 当用户浏览数据时,查询总行数
  • 使用会话中存储的数字作为种子,在每个请求上生成相同的ID“随机”顺序
  • 翻页查看ID,仅从数据库中检索与这些ID匹配的记录
  • 试试这个:

    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;