выбор и отображение ранжированных элементов и голосов пользователей в стиле Reddit, Digg и т. д.

при выборе ранжированных объектов из базы данных (например, статей, за которые проголосовали пользователи), как лучше всего показать:

  • текущая страница товаров
  • рейтинг пользователя за элемент (если он проголосовал)

грубая схема:

articles: id, title, content, ...
user: id, username, ...
votes: id, user_id, article_id, vote_value

лучше / идеально ли:

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

or

  1. выберите текущую страницу элементов и просто «ПРИСОЕДИНЯЙТЕСЬ» к данным голосования из таблицы голосов пользователей

или что-то совсем другое?

Теоретически это происходит в среде с высоким трафиком и с использованием rdbms, например mysql. fwiw, я вижу это со стороны «обдумывания, прежде чем делать», а не «преждевременной оптимизации».

Благодарность!


person Carson    schedule 25.05.2009    source источник
comment
Соединение (вероятно, ЛЕВОЕ СОЕДИНЕНИЕ), вероятно, будет лучше, но это трудно сделать, если вы не набросаете соответствующие столбцы схем соответствующих таблиц.   -  person Alex Martelli    schedule 26.05.2009


Ответы (2)


JOIN будет быстрее; это сэкономит время на обход базы данных и обратно.

Однако я бы не стал беспокоиться об этом, пока вы действительно не получите некоторый трафик. Многие люди высказались против преждевременной оптимизации, я процитирую случайную :

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

person Andomar    schedule 25.05.2009

Если вам нужно заказать голоса, используйте это:

SELECT  *
FROM    (
        SELECT  a.*, (
                SELECT  SUM(vote_value)
                FROM    votes v
                WHERE   v.article_id = a.id
                ) AS votes
        FROM    article a
        )
ORDER BY
        votes DESC
LIMIT 100, 110

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

Если вы хотите отображать только собственные голоса пользователя, используйте LEFT JOIN:

SELECT  a.*, vote_value
FROM    articles a
LEFT JOIN
        votes v
ON      v.user_id = @current_user
        AND v.article_id = a.id
ORDER BY
        a.timestamp DESC
LIMIT 100, 110

Наличие индекса на (vote_user, vote_item) значительно улучшит этот запрос.

Обратите внимание, что вы можете сделать (vote_user, vote_item) PRIMARY KEY для голосов, что еще больше улучшит этот запрос.

person Quassnoi    schedule 25.05.2009
comment
Как я прочитал вопрос, он хотел бы отобразить страницу новостей, а затем получить голоса текущего пользователя за эти элементы. - person Andomar; 26.05.2009