【问题标题】:A function that randomly selects a row from the database!从数据库中随机选择一行的函数!
【发布时间】:2011-07-19 14:15:45
【问题描述】:

我正在创建一个在线商店网站,该网站需要从数据库中选择随机产品的功能。

这个想法是,每次网页加载时都会有一个随机产品的广告!

使用 PHP,我该怎么做?

tbl_products

身份证 代码 标题 股票 成本 rrp

这些是我需要从数据库中访问的行。

谢谢

【问题讨论】:

标签: php mysql


【解决方案1】:

最直接的解决方案是:

SELECT  *
FROM    tbl_products
ORDER BY
        RAND()
LIMIT 1

但是,随着产品数量的增加,效率会降低。

这个解决方案:

效率更高,但仍需要全表扫描。

如果您的产品 id 分布或多或少均匀,请使用:

SELECT  p.*
FROM    (
        SELECT
                (
                (
                SELECT  MAX(id)
                FROM    tbl_products
                ) -
                (
                SELECT  MIN(id)
                FROM    tbl_products
                )
                ) * RAND() AS rnd
        ) q
JOIN    tbl_products p
ON      id >= rnd
ORDER BY
        id
LIMIT 1;

如果你的 id 之间有间隔,那么间隔大之后的产品往往会被更频繁地选择。

您可以为此目的使用一个特殊的唯一列来代替 id,您应该在 cron 作业中填写该列而不会出现空白。

【讨论】:

  • 我会添加 WHERE 库存 > 1,并且在任何时候,库存产品的数量都不会超过 500。您的解决方案是否适用?
  • 请参阅titov.net/2005/09/21/…,了解为什么这可能不是最有效的方法。
  • @Luke:只有500 产品,第一个查询就足够快了。
  • @cwallenpoole - 有点混乱,我问的是 500 种产品是否足够高效! newtron,我看看那个。 quassnoi,谢谢 bud,我会仔细研究这两种解决方案!很棒的答案:)
  • @quassnoi - 对于第二种解决方案,我将如何合并 WHERE stock > 1 in?用 max 函数可以吗?
【解决方案2】:

ORDER BY RAND() 是一个众所周知的解决方案,但存在众所周知的问题。

如果产品ID是一个连续的整数范围并且有一个非平凡的行数,那么SELECT MAX(id) FROM products会好得多,在PHP中生成一个1到结果之间的随机整数,然后做SELECT * FROM products WHERE id IN (x, y, z) 作为第二个查询。如果 id 几乎但不完全连续,您可以调整此解决方案以生成比所需更多的随机 id,以解释并非所有这些都可能有效的事实(id 之间的碎片越多,剩余数字越多你应该生成)。

如果上述方法不可行,那么查询like this 仍然比纯ORDER BY RAND() 更好。

【讨论】:

    【解决方案3】:

    这是一个 PHP 解决方案

    $range_res = mysql_query( " SELECT MAX(id) AS max_id , MIN(id) AS min_id FROM products ");
    $range_row = mysql_fetch_object( $range_res ); 
    $random = mt_rand( $range_row->min_id , $range_row->max_id );
    $res = mysql_query( " SELECT * FROM products WHERE id >= $random LIMIT 0,1 "); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-24
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多