【问题标题】:random data using php & mysql使用 php 和 mysql 的随机数据
【发布时间】:2010-04-20 16:27:59
【问题描述】:

我的mysql数据库结构如下:

CREATE TABLE test (
    id int(11) NOT NULL auto_increment,
    title text NULL,
    tags text NULL,
    PRIMARY KEY (id)
);

字段标签上的数据存储为逗号分隔的文本,如 html、php、mysql、website、html 等... 现在我需要创建一个数组,其中包含大约 50 个从随机记录中随机选择的标签。

目前我正在使用 rand() 从数据库中选择 15 个随机 mysql 数据,然后将 15 个记录中的所有标签保存在一个数组中。然后我使用 array_rand() 来随机化数组并只选择 50 个随机标签。

$query=mysql_query("select * from test order by id asc, RAND() limit 15");
$tags="";
while ($eachData=mysql_fetch_array($query)) {
    $additionalTags=$eachData['tags'];
    if ($tags=="") {
        $tags.=$additionalTags;
    } else {
        $tags.=$tags.",".$additionalTags;
    }
}

$tags=explode(",", $tags);
$newTags=array();
foreach ($tags as $tag) {
    $tag=trim($tag);
    if ($tag!="") {
        if (!in_array($tag, $newTags)) {
            $newTags[]=$tag;
        }
    }
}

$random_newTags=array_rand($newTags, 50);

现在我的数据库中有大量记录,正因为如此; rand() 执行速度非常慢,有时它不起作用。那么谁能告诉我如何正确处理这种情况,以便我的页面正常工作。

【问题讨论】:

  • 分布是否需要尽可能统一? 15 条记录的限制是常数吗?
  • 不。我只需要大约 10-15 个随机记录来确保我最终会得到 50 个随机标签。

标签: php mysql random


【解决方案1】:

永远不要ORDER BY RAND() - 这对性能来说太可怕了。而是在 PHP 中进行随机化。像这样,因为您的 ID 是自动递增的(可能不是最好的方法):

$count = mysql_fetch_assoc(mysql_query("select count(1) as count from test"));
$range = range(0, $count['count']);

$selection = array_rand($range, 50);
$sel_list = implode(',', $selection);

$query = mysql_query("select * from test where id in ($sel_list)");

顺便说一句,你为什么把你的标签放在一个字符串列表中,只是为了以后爆炸那个字符串?只需从一开始就将它们放入一个数组中。

【讨论】:

  • 这假定auto_increment 列中没有间隙。如果您有差距,您可以单独选择记录。它仍然会很快,因为您将为每个查询使用主键索引。 "SELECT * FROM test WHERE id >= $selection LIMIT 1"。或者,如果你没有得到 15 行,就再得到一些。
  • 数据库中字段标签的数据以逗号分隔存储。我将标签集存储在字符串列表中,以便我可以验证和分解标签集并创建一个仅包含有效标签和单个标签的数组。
  • 太棒了,它就像一个魅力,只需稍作修改即可满足我的页面附加要求。
【解决方案2】:

我想你可能知道为什么ORDER BY RAND() 很慢。查询读取所有记录,然后在不借助索引的情况下对它们进行排序。

如果你在0MAX(id) - 15之间选择一个随机数并得到接下来的15行,它是否足够随机?输入的记录是无序的吗?

SELECT * FROM test
WHERE id >= my_random_value
ORDER BY id
LIMIT 15

【讨论】:

  • 首先我需要从表中随机选择 15 条记录。然后将字段“标签”的数据保存在一个数组中,我需要打印 50 个随机标签。我认为您的示例不起作用,因为有时 my_random_value 的返回值可能不存在于数据库中。
  • 我打算采用这种方法,但后来我发现有 15 个具有顺序 ID 的条目不够随机。
  • @Prakash,请注意WHERE 子句中的>=。如果您选择(包括)最小 ID 值和最大 id 值(负 15)之间的随机值,然后选择 id 大于或等于随机值的接下来 15 条记录,您将始终得到至少一条记录,大多数时候,你会得到 15 条记录。如果你得到少于 15 个,那么重复直到你有 15 个。
【解决方案3】:

Marcus 程序可以改进,例如

SELECT * FROM test
WHERE id % round(rand()*(SELECT count(*) FROM test)) = 0
ORDER BY id
LIMIT 15

(而且速度不是太慢)。 唯一的问题是上面的表达式不能保证你会得到 15 条记录。 你想要这样的东西吗?可以改进以保证 15 条记录。

【讨论】:

  • 这听起来不错,但不会返回更多记录。有时它返回空,有时只返回几行,因此我最终无法获得 50 个标签。反正有没有得到更多的行?
  • 是的,通过降低除数 - SELECT count(*) FROM 测试;并在那里输入较小的值,您将有更高的机会选择记录,但仍然不能保证。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多