我希望有一个PHP代码可以逐个绘制一些ID,而无需从MySQL数据库中的表中随机替换。
现在我像这样实现它:
有一个名为box的表
CREATE TABLE box
(
id INT UNSIGNED AUTO_INCREMENT,
PRIMARY KEY (id)
);
假设它包含15条记录,
框
id:
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
=====
已经绘制的ID将被记录并在下一次抽奖中排除。
例如,
一开始,绘图的SQL将是
SELECT id FROM box RAND() LIMIT 1;`.
说结果是4。
然后我画了4,下一个用于绘图的SQL将是
SELECT id FROM box WHERE id != 4 ORDER BY RAND() LIMIT 1;
这次说结果是6。
也就是说,我已经绘制了4和6,因此下一个绘制的SQL将是
SELECT id FROM box WHERE id != 4 AND id != 6 ORDER BY RAND() LIMIT 1;"
问题在于:
如果表'box'包含2000条记录并且我已经绘制了1000多个ID,则下一个绘制的SQL将会很长。 我想知道更长的SQL语句是否会使MySQL中的程序或进程运行得更慢?如果是,是否有解决方案/设计/算法来解决此问题? 表中的记录可能会增加,因此我无法在绘图前对ID进行随机序列。
有关此问题的更多信息:
PHP代码将由多个用户调用,因此每个用户都有一些由他/她绘制的不同ID。
实际上,在我目前的设计中,用户绘制的ID存储在PHP会话变量中。当用户想要绘制时,将访问存储在会话变量中的id,如上所述绘制SQL。
答案 0 :(得分:1)
为什么不在表格中添加另一列来表明是否已绘制该数字?
然后你的查询就变成了:
SELECT id FROM box WHERE drawn = 0 ORDER BY RAND() LIMIT 1
然后,之后:
UPDATE box SET drawn = 1 WHERE id = 43
或您绘制的任何ID。
答案 1 :(得分:1)
编写的大多数查询所用的查询时间大致相同。
顺便提一句,查询中的条件等同于NOT IN,并且您可以更轻松地应用NOT IN
SELECT * FROM box WHERE id NOT IN (a[0],a[1]...)
现在关于增加查询大小是否会减慢MySQL的答案是否定的,不是真的。
关于它为什么不会降低速度的文章是here(请记住,您的查询相当于不在其中)
答案 2 :(得分:1)
如果该框具有固定数量的记录,那么我倾向于采用一种方法为用户提供更多空间,但应该更快地运行。由于order by rand()
。
相反,为每个用户创建一个单独的“框”,并最初进行随机排序:
CREATE TABLE userbox (
userboxid INT UNSIGNED AUTO_INCREMENT,
int boxid,
userid int,
PRIMARY KEY (userboxid),
KEY (userid, userboxid)
);
然后,当用户启动时,插入该用户的框中:
insert into userbox
select id, <userid>
from box
order by rand()
后续检索将使用select语句,例如:
select boxid
from userbox
where userboxid > <last user box id> and userid = <userid>
limit 1
这种方法的优点是,在填充框的开销之后,每次检索下一个id应该只需要查看索引中的下一个值并从数据页中获取框id。
答案 3 :(得分:0)
您可以为每个用户绘制的数字添加另一个表
user_id id
1 129
1 832
2 23
...
然后
SELECT id FROM box WHERE id NOT IN (SELECT id FROM user_drawn WHERE user_id=1) RAND() LIMIT 1;