Вопрос

У меня есть таблица MySQL со многими рядами. Стол имеет колонку популярности. Если я сортирую по популярности, я могу получить ранг каждого товара. Можно ли получить ранг определенного предмета без сортировки всей таблицы? Я так не думаю. Это правильно?

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

Это было полезно?

Решение

Нет никакого способа рассчитать заказ (то, что вы называете рангом) чего-то без первого сортировки стола или сохранение ранга.

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

Выберите все, включая ранг

SET @rank := 0;
SELECT t.*, @rank := @rank + 1
FROM table t
ORDER BY t.popularity;

Чтобы получить элемент с определенным «идентификатором», то вы можете просто использовать подзапрос следующим образом:

Выберите один, включая ранг

SET @rank := 0;
SELECT * FROM (
  SELECT t.*, @rank := @rank + 1
  FROM table t
  ORDER BY t.popularity
) t2
WHERE t2.id = 1;

Другие советы

Вы правы, что второй подход неэффекчен, если столбец RANK обновляется на каждой таблице. Однако в зависимости от того, сколько обновлений существует в базе данных, вы можете рассчитать ранг на каждом обновлении и хранить это - это форма кэширования. Затем вы включаете рассчитанное поле в поле фиксированного значения.

Это видео Крышки кэширования в MySQL, и хотя он является специфическим рельсами, и немного другой формы кэширования - это очень похожая стратегия кэширования.

Если вы используете таблицу InnoDB, вы можете рассмотреть возможность построения кластерного индекса на столбце популярности. (Только если порядок по популярности является частое запрос). Решение также зависит от того, насколько варьировалась колонка популярности (0 - 3 не так хорошо).

Вы можете посмотреть на эту информацию о кластерном индексе, чтобы увидеть, работает ли это для вашего дела: http://msdn.microsoft.com/en-us/library/ms190639.aspx.

Это относится к SQL Server, но концепция такая же, также посмотрите на документацию MySQL на этом.

Если вы делаете это, используя PDO, то вам нужно изменить запрос всего в одном операторе, чтобы заставить его работать должным образом. Видеть PHP / PDO / MYSQL: конвертировать несколько запросов в один запрос

Так что ответ Hoodave становится чем-то вроде:

SELECT t.*, (@count := @count + 1) as rank
FROM table t 
CROSS JOIN (SELECT @count := 0) CONST
ORDER BY t.popularity;

Решение Boyodave очень хорошо. Кроме того, вы можете добавить отдельный рейтинговый столбец, а затем, когда популярность строки UPDATED, запрос, чтобы определить, изменена ли эта популярность обновления, изменила свой рейтинг относительно строки выше и под ним, затем UPDATE 3 ряда затронуты. Вам придется профиль, чтобы увидеть, какой метод более эффективен.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top