我被要求向应用程序添加功能,允许用户在两个选项之间进行投票:A和B.这些问题的表格非常基本:
QUESTIONS
question_id (PK)
option_id_1(FK)
option_id_2(FK)
urgent (boolean)
每次用户投票时,用户投票的内容都存储在同样简单的表格中:
USER VOTES
vote_id (PK)
user_id (FK)
question_id (FK)
当用户请求新问题时,选择出现哪个问题的算法很复杂,但出于我们的目的,我们可以假设它是随机的。那么,问题呢?
每个用户都会对许多问题进行投票。可能有数百甚至数千。我需要确保没有用户被提出他们已经投票的问题,而我猜想的唯一方法是,我猜测,将服务器置于遗忘状态。具体来说,如:
SELECT * from questions WHERE question_id NOT in (SELECT question_id from user_votes WHERE user_id = <user_id>) ORDER BY RAND() LIMIT 1.
[注意:RAND()实际上并不在查询中 - 它只是替代稍微复杂的(order_by)。]
所以,请记住,许多用户很可能已经投票了数百甚至数千个问题,并且不可能按照既定顺序提出问题...任何关于如何排除投票问题的想法击败我的服务器?
所有建议都表示赞赏 - 非常感谢。
答案 0 :(得分:3)
JOIN
运算符比MySQL中的嵌套查询执行得更好(可能已经更新了最新的MySQL版本,但是如果遇到性能问题,我猜我的语句仍然存在)
你可以做的只是将联票投票留在问题上,只挑选那些没有投票的记录(没人投票):
SELECT *
FROM questions q
LEFT JOIN user_votes uv ON
uv.question_id = q.question_id AND
uv.user_id = '<user_id>'
WHERE vote_id IS NULL
答案 1 :(得分:1)
RAND()很讨厌但是这可以减轻问题,同时为您提供所需的结果。看到你已经提到RAND()就是一个例子,我实际上无法提供比下面更具体的建议,但是替换ORDER BY应该可以正常工作。
您可以越多地限制内部查询中的行数,整个查询的执行速度就越快。
SELECT
q.*
FROM (
-- First get the questions which have not been answered
SELECT
questions.*
FROM questions
LEFT JOIN user_votes
ON user_votes.question_id = questions.question_id
AND user_votes.user_id = <user_id>
WHERE user_votes.user_id IS NULL
) q
-- Now get a random 1. I hate RAND().
ORDER BY RAND()
LIMIT 1