SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 22.06.2012 17:00:48

memba
Участник
Зарегистрирован: 11.06.2011
Сообщений: 12

Организация ленты из подписок

Добрый день!

Нужно организовать ленту из подписок пользователя.

Например есть две таблицы:

CREATE TABLE IF NOT EXISTS post (
  id_post INT( 10 ) UNSIGNED NOT NULL,
  id_cattegory tinyint( 3 ) UNSIGNED NOT NULL, -- ID категории где хранится пост
  id_user INT( 10 ) UNSIGNED NOT NULL, -- ID юзера написавшего пост
  text text NOT NULL default '',
  add_date INT( 10 ) UNSIGNED NOT NULL,
  PRIMARY KEY (id_post)
) ENGINE = MYISAM DEFAULT CHARSET = cp1251;


CREATE TABLE IF NOT EXISTS following (
  id_following INT( 10 ) UNSIGNED NOT NULL,
  id_user INT( 10 ) UNSIGNED NOT NULL,
  follow ENUM( 'user',  'cattegory' ) NOT NULL, -- вид подписки (пользователь или категория)
  id_follow INT( 10 ) UNSIGNED NOT NULL, -- ID пользователя или категории в зависимости от вида подписки
  add_date INT( 10 ) UNSIGNED NOT NULL,
  PRIMARY KEY (id_following)
) ENGINE = MYISAM DEFAULT CHARSET = cp1251;


Таблица post хранит посты пользователей
Таблица following хранит подписки пользователей на других пользователей и на категории в которых размещаются посты.

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

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

В голове следующие:

Перебирать огромную таблицу постов (~миллион записей) и проверять каждую запись на существование на неё подписки в таблице following для конкретного пользователя.

SELECT *FROM post WHERE EXISTS ( SELECT *FROM following WHERE id_user='999' AND ((follow='user' AND id_follow=post.id_user) OR (follow='cattegory' AND id_follow=post.id_cattegory)))


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

Другой вариант с объединением таблиц и вложенным запросом в FROM.

SELECT post.* FROM post, (SELECT *FROM following WHERE id_user='999') as foll WHERE (foll.follow='user' AND post.id_user=foll.id_follow) OR (foll.follow='cattegory' AND post.id_cattegory=foll.id_follow)


Но это наверно ещё более страшный способ. Как я понимаю, при перекрёстном объединение, если таблица post содержит миллион записей, а получившиеся таблица foll две записи, то после слияния получится два миллиона записей для поиска.

Вообщем прошу совета у SQL ниндзи. Может я что не так делаю.

Отредактированно memba (22.06.2012 17:08:45)

Неактивен

 

#2 23.06.2012 10:16:05

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Организация ленты из подписок

select ... from
(select follow, id_follow FROM following WHERE id_user=999 and follow='user') foll join post on ((foll.follow='user' AND post.id_user=foll.id_follow) OR (foll.follow='cattegory' AND post.id_cattegory=foll.id_follow));

Неактивен

 

#3 23.06.2012 11:58:51

memba
Участник
Зарегистрирован: 11.06.2011
Сообщений: 12

Re: Организация ленты из подписок

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

Но:

from
(select follow, id_follow FROM following WHERE id_user=999 and follow='user')


Вы указали только "and follow='user'" Значит таблица составляется только из подписок на пользователей, а категорий нет.

Наверно нужно так:

from
(select follow, id_follow FROM following WHERE id_user=999)

Отредактированно memba (23.06.2012 12:04:06)

Неактивен

 

#4 23.06.2012 12:11:57

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Организация ленты из подписок

memba написал:

Наверно нужно так:

from
(select follow, id_follow FROM following WHERE id_user=999)

Да.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson