Нужна поддержка в выяснении запроса для задания cron - PullRequest
2 голосов
/ 22 декабря 2011

У меня есть система голосования за статьи.Статьи хранятся в таблице «истории», а все голоса - в таблице «голоса».идентификатор в таблице «историй» равен номеру элемента в таблице «голосов» (поэтому каждый голос относится к статье с именем элемента).

Я хочу сделать так, чтобы, когда сумма голосов достигла 10, он обновлялся, показывая'field' в таблице 'Stories' со значением "1".

Я думал о настройке задания cron, которое запускается каждый час, чтобы проверять все сообщения с показом = 0. Если показ = 0, тогдасуммирует голоса, относящиеся к этой статье, и установит показ = 1, если сумма голосов> = 10. Я не уверен, что это эффективно, поскольку может потребовать много ресурсов сервера, не уверен.

Так может кто-нибудь предложить работу cron, которая могла бы выполнить задачу?

Вот моя структура базы данных:

Таблица историй

enter image description here


Таблица голосов

enter image description here


Редактировать:

Например, эта строка из таблицы «историй»:

id | 12
st_auth | имя автора
st_date | дата истории
st_title | название истории
st_category | категория истории
st_body | тело истории
показ | 0 для неутвержденных и 1для утвержденных

Эта строка связана с этой строкой из таблицы «голосов»

id | 83 item_name | 12 (id статьи) voice_value | 1 для upvote -1 для downvote ...

Ответы [ 3 ]

2 голосов
/ 22 декабря 2011

Пара вещей:

  1. Почему вы назвали столбец item_name в таблице голосов, когда на самом деле это идентификатор таблицы статей? Я бы рекомендовал сделать это совпадением для таблицы article, так как это int (11) vs var_char (255). Кроме того, вы должны добавить ограничение внешнего ключа в таблицу голосов, так что, если статья будет удалена, вы не осиротите строку в таблице голосов.

  2. Почему столбец vote_value является целым (11)? Если это может быть только два состояния (1 или -1), вы можете сделать tinyint (1) со знаком (для -1).

  3. Столбец ip в таблице голосов немного интересен. Если вы регулируете «уникальные» голоса по ip, учитывали ли вы прокси ips? Примерно так должно быть обработано на уровне аккаунта, чтобы несколько пользователей с одного IP-адреса прокси могли отдавать отдельные голоса.

  4. Я бы не стал делать cronjob для определения того, должен ли столбец showing быть помечен 0 или 1. Скорее, я бы выставлял счет каждый раз, когда голос был отдан против статьи. Поэтому, если кто-то проголосовал за или против, рассчитайте новое значение истории и сохраните ее в кеше для будущих чтений.

1 голос
/ 22 декабря 2011

Используя этот запрос, вы получите список всех статей плюс столбец, содержащий количество связанных голосов.

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;
1 голос
/ 22 декабря 2011

Я бы использовал триггер (вставьте триггер) и обработал вашу логику там (в самой базе данных)? Это полностью удалит код опроса (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
...