Как выбрать похожие сообщения (в чем-то похожем на стену Facebook)? - PullRequest
0 голосов
/ 05 июля 2011

У меня есть что-то вроде сборки стены Facebook на PHP, которая использует базу данных MySQL.

Состав:

  • Категории создаются администраторами и не предназначены для частого изменения,
  • Группы создаются пользователями. Количество их может быть очень огромным. Они как «ребенок» одной категории,
  • Сообщения также создаются пользователями. Они похожи на «ребенка» одной группы, а эта группа похожа на «ребенка» одной категории;

Последнее, что комментарии. Они хранятся в той же таблице, где находятся сообщения, но со строкой «reply», в которой указан идентификатор сообщения, похожий на «parent».

Вот простой пример:

Food (category):

-> Kebabs (group)

->-> What's your fave kebab, folks? (post)

->->-> I love doner kebab! (post too, but displayed as comment)

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

Эти отношения на данный момент:

  • Пользователь является автором сообщения,
  • Пользователь прокомментировал сообщение (это сообщение нельзя сделать самому),
  • Другой пользователь прокомментировал группу, в которой "наш" пользователь является членом;

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

Вот запрос:

SELECT `posts`.`id`, `posts`.`created_at`, `posts`.`content`, `posts`.`replies`, `groups`.`id` AS `group_id`, `groups`.`name` AS `group_name`, `users`.`name`, `users`.`surname`, `users`.`avatar`
FROM `posts`
JOIN `groups` ON (`groups`.`id` = `posts`.`group_id`)
JOIN `users` ON (`users`.`id` = `posts`.`user_id`)
WHERE `posts`.`status` = 1 AND `posts`.`post_id` = 0 AND `posts`.`user_id` = '33'
ORDER BY `posts`.`id` DESC
LIMIT 10
OFFSET 0

Edit:

Вот структура таблицы:

CREATE TABLE `bio_community_categories` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

CREATE TABLE `bio_community_groups` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `category_id` int(10) unsigned NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `created_at` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `description` text,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;

CREATE TABLE `bio_community_posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `group_id` int(10) unsigned NOT NULL,
  `post_id` int(11) unsigned NOT NULL DEFAULT '0',
  `created_at` int(11) NOT NULL,
  `content` text NOT NULL,
  `status` tinyint(1) unsigned NOT NULL DEFAULT '1',
  `replies` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `status` (`status`),
  KEY `post_id` (`post_id`),
  KEY `user_id` (`user_id`),
  KEY `group_id` (`group_id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `surname` varchar(50) NOT NULL,
  /* Etc.. */
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `bio_community_categories` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

CREATE TABLE `bio_community_groups` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `category_id` int(10) unsigned NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `created_at` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `description` text,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;

CREATE TABLE `bio_community_posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `group_id` int(10) unsigned NOT NULL,
  `post_id` int(11) unsigned NOT NULL DEFAULT '0',
  `created_at` int(11) NOT NULL,
  `content` text NOT NULL,
  `status` tinyint(1) unsigned NOT NULL DEFAULT '1',
  `replies` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `status` (`status`),
  KEY `post_id` (`post_id`),
  KEY `user_id` (`user_id`),
  KEY `group_id` (`group_id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `surname` varchar(50) NOT NULL,
  /* Etc.. */
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1 Ответ

2 голосов
/ 06 июля 2011

Предположим, что также будет таблица групповых отношений пользователей, скажем, "groups_members", поэтому ваш запрос будет выглядеть следующим образом:

SELECT `posts`.`id`, `posts`.`created_at`, `posts`.`content`, `posts`.`replies`, `groups`.`id` AS `group_id`, `groups`.`name` AS `group_name`, `users`.`name`, `users`.`surname`, `users`.`avatar`
FROM `posts`
JOIN `groups` ON (`groups`.`id` = `posts`.`group_id`)
JOIN `users` ON (`users`.`id` = `posts`.`user_id`)
WHERE `posts`.`status` = 1 AND `posts`.`post_id` = 0 AND  (`posts`.`user_id` = '33' OR `bio_community_posts`.`group_id` IN (SELECT `group_id` FROM `groups_members` WHERE `user_id` =33)) 
ORDER BY `posts`.`id` DESC
LIMIT 10
OFFSET 0

Из приведенного выше запроса вы получите сообщения, опубликованные пользователем 33+ те сообщения из группы, в которую входит пользователь 33.

...