Каков наилучший подход для перечисления недавних действий пользователя в PHP / MySQL? - PullRequest
0 голосов
/ 11 марта 2009

Я хочу перечислить последние действия пользователя на моем сайте, не выполняя слишком много запросов. У меня есть таблица, в которой я перечисляю все, что пользователь сделал с датой.

page_id - reference_id - reference_table - created_at - updated_at

reference_id - это идентификатор, который мне нужно искать в reference_table (пример: комментарии). Если бы я сделал SELECT в своей таблице активности, мне бы пришлось запросить:

SELECT * FROM reference_table where id = reference_id LIMIT 1

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

Например, если это комментарий, мне нужно получить имя автора, комментарий, если это ответ, мне нужно получить имя пользователя в оригинальном комментарии и т. Д.

Я просмотрел ключевое слово UNION, чтобы объединить все мои таблицы, но я получаю сообщение об ошибке

1222 - Используемые операторы SELECT имеют различное количество столбцов

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

Я также изучил оператор CASE, который также требует, чтобы количество столбцов совпадало, если я правильно помню (хотя я могу ошибаться для этого).

Кто-нибудь имеет представление о том, как я мог бы перечислить последние действия пользователя, не выполняя слишком много запросов?

Я использую PHP и MySQL.

Ответы [ 4 ]

4 голосов
/ 11 марта 2009

Вы, вероятно, хотите разделить различные виды деятельности на разные таблицы. Это даст вам больше гибкости в том, как вы запрашиваете данные.

Если вы решите использовать UNION, убедитесь, что вы используете одинаковое количество столбцов в каждом запросе выбора, из которого состоит UNION.

EDIT: Я получил отрицательный ответ за свой ответ, так что, возможно, я смогу дать лучшее объяснение.

Разделить таблицу на отдельные таблицы и UNION

Я рекомендовал эту технику, потому что она позволит вам более подробно рассказать о ресурсах, для которых вы запрашиваете. Удобно иметь одну таблицу для вставки, но вам всегда нужно будет выполнять отдельные запросы для объединения с другими таблицами, чтобы получить значимую информацию. Кроме того, схема базы данных будет запутана тем, что один столбец является внешним ключом для разных таблиц в зависимости от данных, хранящихся в этой строке.

Вы можете иметь таблицы для комментариев, обновления и подписки. Они будут иметь свои собственные данные, которые могут запрашиваться индивидуально. Скажем, если вы хотите посмотреть на ВСЕ пользовательские действия, вы можете легко использовать UNION следующим образом:

(SELECT 'comment', title, comment_id AS id, created FROM comment)
UNION
(SELECT 'update', title, update_id as id, created FROM update)
UNION
(SELECT 'subscription', title, subscription_id as id, created 
  FROM subscription)
ORDER BY created desc

Это обеспечит вам просмотр списка. Затем вы можете ссылаться на детали каждого типа или загружать его при вызове ajax.

Вы можете сделать это с помощью метода, который вы используете в настоящее время, но это фактически устранит необходимость в 'reference_table' и позволит выполнить то же самое более чистым способом (IMO).

1 голос
/ 11 марта 2009

С UNION вам не нужно получать все столбцы из каждой таблицы, если только все столбцы имеют одинаковые типы данных.

Так что вы можете сделать что-то вроде этого:

SELECT name, comment as description
FROM Comments

UNION

SELECT name, reply as description
FROM Replies

И не имеет значения, если Comments и Replies имеют одинаковое количество столбцов.

1 голос
/ 11 марта 2009

Проблема в том, что UNION следует использовать только для объединения похожих наборов записей. Если вы попытаетесь объединить два разных запроса (например, с разными извлекаемыми столбцами), это будет ошибкой.

Если природа запросов различна (с различным количеством столбцов или типов данных), вам нужно будет сделать несколько разных запросов и обрабатывать их все по отдельности.

Другим подходом (менее элегантным, я полагаю) будет СЛЕДУЮЩЕЕ СОЕДИНЕНИЕ вашей таблицы действий со всеми остальными, так что вы получите набор записей с большим количеством столбцов и вам нужно будет проверить каждую строку столбцы следует использовать в зависимости от характера деятельности.

Опять же, я бы предпочел придерживаться первого, поскольку второе вызывает довольно редкий набор записей.

0 голосов
/ 11 марта 2009

Это действительно зависит от количества трафика на вашем сайте. Подход объединения является простым и, возможно, правильным, логически, но вы будете страдать от производительности, если ваш сайт сильно загружен, поскольку индексирование запроса UNIONed затруднено.

Присоединение может быть хорошим, но опять же, с точки зрения производительности и ясности кода, это не лучший способ.

Еще один совершенно другой подход заключается в создании таблицы «действия», которая будет обновляться вместе с действием (в дополнение к реальной деятельности, только для этой цели). В старых терминах правильности БД вы должны избегать этого подхода, поскольку он будет создавать дубликаты данных в вашей системе, однако я нашел его очень полезным с точки зрения производительности.

[Еще одно замечание о подходе UNION, если вы решите принять его: если у вас есть разница в длине параметров, вы можете ВЫБРАТЬ фиктивные параметры в некоторых объединениях, например .. (SELECT UserId, UserName ОТ пользователей) UNION (ВЫБЕРИТЕ 0, Имя пользователя из заметок)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...