Php 通过MySQL获取最小随机记录集

Php 通过MySQL获取最小随机记录集,php,mysql,sql,random,Php,Mysql,Sql,Random,我正试图找到一种获取X个随机记录的正确方法。我还想检查一个特定记录的使用情况,这样我就不会像其他人一样经常使用同一个随机记录 我正在用这3个表测试集合,一个表用于问题,一个表用于用户,一个表用于特定用户的问题。我想用大约6000个问题来完成这个任务 CREATE TABLE `questions` ( `id` int(11) NOT NULL AUTO_INCREMENT, `question` varchar(128) DEFAULT NULL, PRIMARY KEY (`id

我正试图找到一种获取X个随机记录的正确方法。我还想检查一个特定记录的使用情况,这样我就不会像其他人一样经常使用同一个随机记录

我正在用这3个表测试集合,一个表用于问题,一个表用于用户,一个表用于特定用户的问题。我想用大约6000个问题来完成这个任务

CREATE TABLE `questions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `question` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `served` (
  `user` int(11) NOT NULL DEFAULT '0',
  `question` int(11) NOT NULL DEFAULT '0',
  `count` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`user`,`question`),
  KEY `count` (`count`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我发现查询可以很好地从问题表中获取随机记录,如下所示:

SELECT  id, question
        FROM    (
                SELECT  @cnt := COUNT(*) + 1,
                        @lim := 10
                FROM    questions
                ) vars
        STRAIGHT_JOIN
                (
                SELECT  q.*,
                        @lim := @lim - 1
                FROM    questions q 
                WHERE   (@cnt := @cnt - 1)
                        AND RAND() < @lim / @cnt
                ) i
SELECT  id, question, count
        FROM    (
                SELECT  @cnt := COUNT(*) + 1,
                        @lim := 10
                FROM    questions
                ) vars
        STRAIGHT_JOIN
                (
                SELECT  q.*,
                        s.count,
                        @lim := @lim - 1
                FROM    questions q
                LEFT JOIN served s
                ON s.question = q.id
                WHERE   (@cnt := @cnt - 1)
                        AND RAND() < @lim / @cnt
                ORDER BY count ASC) i

人们在MySQL中获取随机记录的常见方式如下:

SELECT questions.* FROM questions
LEFT JOIN served
ON served.question = questions.id
ORDER BY IFNULL(served.count, 0) + RAND()
LIMIT 10
要获得10条随机记录:

SELECT * FROM questions
ORDER BY RAND()
LIMIT 10
当然,很明显,这会获取数据库中的所有记录,然后对它们进行随机排序,以获得10条记录。它实际上并不只是从数据库中随机选择10条记录。但是,这种方法很容易防止重复

现在,使用同样的技巧,如果你想喜欢服务较少的问题,你可以这样做:

SELECT questions.* FROM questions
LEFT JOIN served
ON served.question = questions.id
ORDER BY IFNULL(served.count, 0) + RAND()
LIMIT 10
调整算法,改变你喜欢的发球数量

有更多性能更好的方法来获取随机记录,例如获取最大主键值(假设自动递增),然后对其使用RAND(),然后只拾取一条记录。您可以使用
LIMIT 1
,以防RAND()返回键中的间隙。但是,如果重复此过程以返回多个记录,则可能会有重复的记录

如果您有连续的自动增量值,那么可以轻松地利用PHP选择一组随机键,然后分别获取每条记录。如果它们不是连续的,则首先获取密钥列表


这些技术在本书第16章随机选择中有更详细的介绍。

考虑提供适当的DDL(和/或sqlfiddle)和少量合法结果。我用我的测试数据添加了一个URL+我希望我的第二次查询可以做的事。我刚刚修复了第二次查询中的一个错误。在第二次查询中,它仍然选择已送达的问题,而不是未送达的问题。@Wesso,抱歉。我不知道我在想什么。我已经更新了查询。请现在就试试。最后使用了一个修改过的查询,其中包含了一点您的想法。