我有一个文章投票系统。文章存储在“故事”表中,所有投票都存储在“投票”表中。 'stories'表中的id等于'votes'表中的item_name(因此每个投票都与item_name的item相关)。
我想这样做,当总票数达到10时,它会更新'故事'表中的'显示'字段为“1”的值。
我正在考虑设置一个每小时运行一次的cron作业,以检查所有显示为0的帖子。如果显示= 0,那么它将总结与该文章相关的投票并设置显示= 1如果投票总和> = 10.我不确定它是否有效,因为它可能占用大量服务器资源,不确定。
那么有人可以建议一个可以完成任务的cron工作吗?
这是我的数据库结构:
故事表
投票表
编辑:
例如来自'stories'表的这一行:
id | 12
st_auth | 作者姓名
st_date | 故事日期
st_title | 故事标题
st_category | 故事类别
st_body | 故事体
显示| 0表示未经批准,1表示已批准
此行与“投票”表格中的这一行相关
id | 83 item_name | 12(文章ID) vote_value | 1 for upvote -1 for downvote ...
答案 0 :(得分:2)
一些事情:
为什么在投票表中为列item_name
命名,当它实际上是文章表的ID时?我建议在文章表中使它匹配,因为它是一个int(11)和一个var_char(255)。此外,您应该将一个外键约束添加到投票表中,因此如果文章被删除,您不会在投票表中孤立一行。
为什么vote_value
列为int(11)?如果它只能是两个状态(1或-1),你可以做一个tinyint(1)签名(对于-1)。
投票表中的ip
列有点令人担忧。如果您通过IP管理“独特”投票,您是否考虑代理ips?这样的事情应该在帐户级别处理,因此来自同一代理IP的多个用户可以发出个人投票。
我不会做一个cronjob来确定showing
列是否应标记为0或1.相反,我会在每次对该文章投票时发出一个计数。因此,如果有人投票或投票,计算故事的新价值,并将其存储在缓存中以备将来阅读。
答案 1 :(得分:1)
我会使用触发器(插入触发器)并在那里处理你的逻辑(在数据库本身)? 这将完全删除轮询代码(cron job)。 我还会保留你的外键(在VOTES中)与主键(在STORIES中)相同(至少是类型)?
从长远来看,使用触发器代替轮询将更加清晰。
您没有指定数据库,但在TSQL(对于SQL Server)中,它可能接近此
CREATE TRIGGER myTrigger
ON VOTES
FOR INSERT
AS
DECLARE @I INT --HOLDS COUNT OF VOTES
DECLARE @IN VARCHAR(255) --HOLDS FK ID FOR LOOKUP INTO STORIES IF UPDATE REQUIRED
SELECT @IN = ITEM_NAME FROM INSERTED
SELECT @I = COUNT(*) FROM VOTES WHERE ITEM_NAME = @IN
IF (@I >= 10)
BEGIN
UPDATE STORIES SET SHOWING = 1 WHERE ID = @IN --This is why your PK/FK should be refactored
END
答案 2 :(得分:1)
使用此查询,您将获得所有文章的列表以及包含相关投票数的列。
SELECT s.*, SUM(v.vote_value) AS votes_total
FROM stories AS s INNER JOIN votes AS v
ON v.item_name = s.id
GROUP BY v.vote
这样,您就可以创建一个视图,您可以在votes_total > 10
上对其进行过滤,而无需使用cron作业。
或者您可以将其用作普通查询,如下所示:
SELECT * FROM (
SELECT s.*, SUM(v.vote_value) AS votes_total
FROM stories AS s INNER JOIN votes AS v
ON v.item_name = s.id
GROUP BY v.vote
) WHERE votes_total > 10;