У меня есть четыре таблицы: projects
, posts
, users
а также project_users
, Некоторые пользователи подключены к некоторым проектам через project_users
Таблица. Каждый проект содержит ряд строк из posts
Таблица. Довольно прямо вперед.
Пользователи могут редактировать строки сообщений, и каждый раз, когда происходит обновление, user id
а также timestamp
должны быть сохранены, чтобы другие пользователи могли видеть, что нового, а что нет. Должен ли я сохранить эту информацию в 1) строке сообщения, сохраняя последний редактор и время для каждой строки, или я должен рассмотреть 2) целую отдельную таблицу журнала? Каковы преимущества каждого случая?
Когда это будет решено, я хочу время от времени запускать скрипт, который обновляет содержимое сайта, если кто-либо еще обновил какие-либо строки (толчок бедняка). Чтобы дать мне некоторую перспективу. Это большой запрос, чтобы спросить базу данных, скажем, с 1 миллионом сообщений: «проверьте, есть ли в этом проекте какие-либо посты, где какой-либо пользователь, кроме вас, обновил после отметки времени x
«Просто спрашиваю, потому что я часто выполняю этот запрос.
Гораздо более быстрым способом было бы зарегистрировать последний редактор в строках проектов или пользователей проекта, но с одновременным редактированием нескольких человек, это было бы менее точно, и также нет способа увидеть, какие строки были обновлены. Имеет смысл?
Используйте решение (1). Это чистый дизайн и с ним легко работать.
Когда вы получаете post
данные для формы редактирования, сохраните updated_at
отметка времени в скрытом поле. Затем запускайте Ajax-запрос каждые X секунд, чтобы проверить, была ли изменена временная метка. Запрос прост:
SELECT updated_at FROM posts WHERE post_id = ?
Поскольку вы фильтруете по первичному ключу, запрос будет очень быстрым даже с огромной таблицей.
Теперь сравните извлеченную метку времени с тем, что хранится в скрытом поле. Если это изменилось — оповестить пользователя (редактор).
Как вы уже поняли, возможно, что другой пользователь обновит сообщение между двумя Ajax-запросами. Так что вам следует также проверять наличие обновлений только перед сохранением данных формы. Не забудьте использовать транзакцию и заблокировать строку:
Псевдокод:
START TRANSACTION
SELECT updated_at FROM posts WHERE post_id = ? FOR UPDATE
if ($row->updated_at == $form->updated_at)
then update row
else notify the user that he is unlucky ;-(
COMMIT
Конечно, вы также можете использовать решение (2) и добавить отдельную таблицу post_updates(post_id, user_id, updated_at)
, Чтобы получить последнюю метку времени, вы должны выполнить:
SELECT MAX(updated_at) as updated_at
FROM post_updates
WHERE post_id = ?
Он должен работать довольно быстро с индексом на (post_id, updated_at)
, Но не усложняйте ситуацию, если у вас нет требований, которые могли бы принести пользу этой таблице.
Других решений пока нет …