【发布时间】:2011-09-03 21:19:03
【问题描述】:
我有一个图片数据库,我想让访问者浏览图片。我有一个“下一个”和一个“上一个”链接。
但我想要的是向每个访问者展示图片的顺序。我怎样才能做到这一点?如果我使用 ORDER BY RANDOM(),我有时会显示重复的图像。
有人可以帮帮我吗?谢谢!
【问题讨论】:
我有一个图片数据库,我想让访问者浏览图片。我有一个“下一个”和一个“上一个”链接。
但我想要的是向每个访问者展示图片的顺序。我怎样才能做到这一点?如果我使用 ORDER BY RANDOM(),我有时会显示重复的图像。
有人可以帮帮我吗?谢谢!
【问题讨论】:
你可以尝试在随机函数中使用种子:
SELECT something
FROM somewhere
ORDER BY rand(123)
123 是种子。 Random 应该返回相同的值。
【讨论】:
CREATE TABLE test (i INT);,然后在表中插入一些值,然后使用SELECT * FROM test ORDER BY RAND(1)。重复此操作,您将以相同的随机顺序看到结果。然后尝试使用RAND(2)。
问题在于每个页面都会再次运行RAND(),并且无法知道返回的图片之前是否已经返回。您必须以一种可以过滤掉前几页中已经显示的图片的方式来编写查询,这样RAND() 将有更少的选项可供选择。
一个想法是随机化图片,选择 ID,将 ID 存储在会话中,然后使用这些 ID SELECT。这样一来,每个用户都将随机获得图片,但他们将能够通过它们进行分页,而无需在每个页面上重新随机化它们。
所以,类似:
SELECT id FROM pictures ORDER BY RAND() LIMIT x 如果您还没有会话中的 IDSELECT ... FROM pictures WHERE id IN (IDs from session) LIMIT x另一个想法是在会话中存储用户已经看到的 ID 并将它们过滤掉。例如:
SELECT ... FROM pictures ORDER BY RAND() LIMIT x 如果会话不包含任何 IDSELECT ... FROM pictures WHERE id NOT IN (IDs from session) ORDER BY RAND() LIMIT x正如izi 指出的那样,另一种方法似乎是使用种子。我不得不说我不知道种子,但对于完全相同的种子值,它似乎返回完全相同的结果。因此,运行您通常的查询并使用RAND(seed) 而不是RAND(),其中“seed”是唯一的字符串或数字。您可以使用会话 ID 作为种子,因为它保证对每个访问者都是唯一的。
【讨论】:
您可以按照 izi 的建议播种随机函数,或者按照 rdineiu 的建议跟踪访问过的图像与未访问过的图像。
我想强调的是,这两个选项都不会表现良好。要么会导致您使用任意标准对整个表(或感兴趣的部分)进行排序,并提取顶部的n 行,可能带有偏移量。它会非常慢。
因此,考虑一下每个访问者应该获得不同的图像顺序是多么重要。可能,它不会那么 重要,只要事情看起来随机。假设是这种情况,请考虑这个替代方案......
在您的表中添加一个额外的float 字段,将其命名为sort_ord。 在其上添加索引。在每次插入或更新时,为其分配一个随机值。这里的重点是在不影响性能的情况下以看似随机的顺序结束(从访问者的角度来看)。
这样的设置将允许您获取顶部的n 行并使用索引对图像进行分页,而不是对整个表格进行排序。
您可以选择让 cron 作业定期设置一个新值:
update yourtable
set sort_ord = rand();
您也可以选择创建多个此类字段,并在访问者访问您的网站(cookie 或会话)时为其分配一个。
【讨论】:
ORDER BY RAND 将做需要做的事情,而不会看到任何性能问题。
这将解决:
SELECT DISTINCT RAND() as rnd, [rest of your query] ORDER BY rnd;
【讨论】:
使用 RAND(SEED)。来自文档:“如果指定了常量整数参数 N,则将其用作种子值。”(http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand)。
在上面的示例中,结果顺序始终相同。您只需更改种子 (351) 即可获得新的随机顺序。
SELECT * FROM your_table ORDER BY RAND(351);
您可以在每次用户点击第一页时更改种子。
【讨论】:
如果没有看到 SQL,我猜你可以尝试 SELECT DISTINCT...
【讨论】:
SELECT DISTINCT image FROM images ORDER BY RANDOM()