2

我有一个文章投票系统。文章存储在“故事”表中,所有投票都存储在“投票”表中。'stories' 表中的 id 等于 'votes' 表中的 item_name(因此每个投票都与 item_name 的文章相关)。

我想这样做,所以当投票总和达到 10 时,它会将“故事”表中的“显示”字段更新为“1”的值。

我正在考虑设置一个每小时运行一次的 cron 作业,以检查所有显示 = 0 的帖子。如果显示 = 0,它将汇总与该文章相关的投票,如果投票总和 >= 10,则设置显示 = 1 .我不确定它是否有效,因为它可能会占用大量服务器资源,不确定。

那么任何人都可以建议一个可以完成任务的 cron 工作吗?

这是我的数据库结构:

故事表

在此处输入图像描述


投票表

在此处输入图像描述


编辑:

例如“故事”表中的这一行:

编号| 12
st_auth | 作者姓名
st_date | 故事日期
st_title| 故事标题
st_category| 故事类别
st_body| 故事正文
展示| 0 表示未通过,1 表示已批准

这一行与“投票”表中的这一行相关

编号| 83 物品名称| 12(文章编号) vote_value| 1 表示赞成 -1 表示反对...

4

3 回答 3

2

几件事:

  1. 为什么要item_name在 votes 表中命名该列,而实际上它是 article 表的 id?我建议在文章表上进行匹配,因为它是 int(11) 与 var_char(255)。此外,您应该在 votes 表中添加一个外键约束,因此如果一篇文章被删除,您不会孤立 votes 表中的一行。

  2. 为什么该vote_value列是 int(11)?如果它只能是两种状态(1 或 -1),你可以做一个 tinyint(1) 签名(对于 -1)。

  3. 投票表中的ip列有点令人担忧。如果您通过 ip 管理“唯一”投票,您是否考虑了代理 ip?这样的事情应该在帐户级别处理,因此来自同一代理 IP 的多个用户可以发出单独的投票。

  4. 我不会做一个 cronjob 来确定该showing列应该标记为 0 还是 1。相反,我会在每次对文章投反对票时发出计数。因此,如果有人赞成或反对,计算故事的新价值,并将其存储在缓存中以供将来阅读。

于 2011-12-21T22:52:39.710 回答
1

我会使用触发器(插入触发器)并在那里处理您的逻辑(在数据库本身中)?这将完全删除轮询代码(cron 作业)。我还会让你的外键(在 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
于 2011-12-21T22:43:09.133 回答
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;
于 2011-12-21T22:46:48.120 回答