我每天都在为一个评级网站运行一个 cronjob,该网站运行一个脚本,从每个类别中选择 3 张随机图像,然后访问者可以对图像进行相互评级,例如"图像 1 与图像 2 ->你最喜欢哪一个",这效果很好。
问题是假设有 2 个相同类型的图像
让我们假设
- ID 1是福特野马GT前视图 ID
- 2是福特野马GT前视图,与ID 1略有不同
这是一个问题,因为如果同时选择了id 1和id 2,那么就像说两个完全相同的图像彼此相对一样?所以我创建了一个"分隔符列",在其中我为代表相同数字的图像提供相同的数字,因此在此简化的情况下,id 1 和 id 2 都具有分隔符编号 1 :)
数据库结构
桌车
cars_id | cars_category | cars_source | separator
--------+---------------+---------------+-----------
1 | 1 | 123.jpg | 1
2 | 1 | 242.jpg | 1
3 | 2 | 532.jpg | 2
4 | 2 | 531.jpg | 3
5 | 2 | 45fd.jpg | 3
6 | 3 | da3.jpg | 4
当前的PHP脚本,从每个类别中选择3个随机图像
$cat1 = 1;
$cat2 = 2;
$cat3 = 3;
$stmt = $dbCon->prepare(" INSERT INTO daily_versus ( daily_versus_source, daily_versus_category) "
. " (SELECT cars_source, cars_category "
. " FROM cars "
. " WHERE cars_category IN (?) ORDER BY RAND() LIMIT 3) "
. " UNION "
. " (SELECT cars_source, cars_category "
. " FROM cars "
. " WHERE cars_category IN (?) ORDER BY RAND() LIMIT 3) "
. " UNION "
. " (SELECT cars_source, cars_category "
. " FROM cars "
. " WHERE cars_category IN (?) ORDER BY RAND() LIMIT 3) ");
$stmt->bind_param('iii', $cat1, $cat2, $cat3);
if ($stmt->execute()) {
echo "Success VERSUS/INSERT";
} else {
echo "Fail VERSUS/INSERT";
}
以上是一种魅力,但是集成分隔符编号以便无法选择两辆相同汽车的最聪明方法是什么......所以基本上如果选择了分隔符编号为"X"的汽车,脚本就不能选择另一辆分隔符编号相同的汽车吗?
最简单的方法是按分隔符对每个查询进行分组。
...
(SELECT cars_source, cars_category
FROM cars
WHERE cars_category IN (?)
GROUP BY SEPARATOR
ORDER BY RAND() LIMIT 3)
...
MySQL将从每个组中获取一个"随机"值。 但是,它并不是真正随机的,对于每个分隔符组,每当选择该分隔符时,它可能只会取一个(并且始终相同的)值。
更好 ( -- 在使用前开始评论/剥离)
...
(SELECT cars_source, cars_category
FROM
(select
(select id -- one random id, for each of the 3 random separators
from cars
where separator = ocars.separator -- will be a diff separator for each row in the outer query
order by rand() limit 1
) as rand_id
from cars as ocars
WHERE cars_category IN (?)
group by separator -- each separator only once
order by rand() -- random separators
limit 3 -- 3 random separators
) as cars_id
left join cars on cars.id = cars_id.rand_id -- join the full row for each rand_id
)
...
你应该有索引,在id和分隔符上, 也许还有类别
按 [分隔符] 排名并选择顶部。