Оптимальный запрос для проблемы - PullRequest
0 голосов
/ 11 мая 2011

У меня есть таблица news, как показано ниже:

CREATE TABLE `news` (
  `title` varchar(255) NOT NULL,
  `hash` char(40) NOT NULL,
  PRIMARY KEY (`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

И еще одна таблица votes:

CREATE TABLE `votes` (
  `hash` char(40) NOT NULL,
  `user_id` varchar(255) NOT NULL,
  `vote_type` enum('up','down') DEFAULT NULL,
  PRIMARY KEY (`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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

this_is_a_title hash_12312312 NULL

this_is_a_title hash_12312313 up

this_is_a_title hash_12312314 NULL

this_is_a_title hash_12312315 down

Можете ли вы предложить оптимальный одиночный запрос для этого?

Я думаю, что мой вопрос не был ясен. Простите за это. Под полем NULL я имел в виду нового, у которого нет ни одного голоса, отданного этим пользователем или кем-либо еще.


Моя версия -

SELECT news.*, votes.vote_type
FROM news 
LEFT OUTER JOIN votes 
ON votes.`hash` = news.`hash` 
AND votes.`user_id` = #

Ответы [ 4 ]

1 голос
/ 11 мая 2011
SELECT * FROM news JOIN votes ON news.hash = votes.hash WHERE votes.user_id = #;

Это SELECT всех голосов в новостных статьях для конкретного пользователя с идентификатором #. Таблицы объединяются с hash, который является первичным ключом. Так что это оптимально, учитывая вашу текущую конфигурацию. Вы можете добавить индекс для user_id для дополнительной оптимизации.

Примечание: Поскольку вы ищете оптимальное , я бы посоветовал вам не использовать LEFT JOIN. Предполагая, что со временем news статьи будут расти, использование прямой JOIN ограничит набор результатов только теми голосами, которые подал пользователь. Который в среднем должен быть значительно меньше. Однако вам придется компенсировать это в своей логике - то есть отсутствие записи новостей означает отсутствие голосования против NULL результата.

0 голосов
/ 09 октября 2011

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

SELECT news.*, votes.vote_type
FROM news 
LEFT OUTER JOIN votes 
ON votes.`hash` = news.`hash` 
AND votes.`user_id` = #
0 голосов
/ 11 мая 2011

Поскольку этот хэш является первичным ключом обеих таблиц, я считаю, что для оптимального запроса вам нужно только ВНУТРЕННЕЕ СОЕДИНЕНИЕ.

SELECT
    n.title,
    v.hash,
    v.vote_type
FROM
    votes v
    INNER JOIN news n USING(hash)
WHERE 
    v.user_id=123
0 голосов
/ 11 мая 2011
SELECT news.title, news.hash, votes.vote_type 
FROM news 
LEFT JOIN votes USING(hash) 
WHERE votes.user_id = @my_user_id

Вот хорошая разбивка различных типов объединений В чем разница между левым, правым, внешним и внутренним объединениями?

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