2012-05-17 3 views
0

Я проектирую сайт как pinterest (для изучения), и я хочу знать, какой запрос я должен сделать на главной странице, чтобы показать поток пользователя.Как избежать этого сложного запроса?

Я создал эти 6 столов:

users 
boards 
pictures 
boards_pictures (many-to-many table) 
followers 
comments 

И в доме, я делаю этот запрос, чтобы получить фотографии всех последователей.

SELECT users.username, pictures.link, comments.comment, boards.title 
FROM boards_pictures, pictures, followers, users, comments, boards 
WHERE (boards_pictures.id_user = followers.id_following) 
    AND (boards_pictures.id_picture = pictures.id) 
    AND (followers.id_user = $_session['userid']) 
    AND (users.id = followers.id_following) 
    AND (comments.picture_id = pictures.id) 
    AND (boards.id = boards_pictures.boards_id) 

Есть ли способ избежать этого сложного запроса (JOIN с 6 таблицами)?

+2

На это немного сложно ответить, не зная структуры таблицы для каждой таблицы. – saluce

+1

присоединиться? Я не вижу ни одного одного JOIN – mkk

+2

Это не приближается к сложному запросу (я пересматривал один из 1000 строк ранее ранее). Если вам нужно, чтобы все шесть таблиц присоединились ко всем из них, но никогда не использовали неявные объединения, они очень плохая практика программирования и антиспам SQL. Нет смысла учиться неправильно, использовать явные объединения только с этого момента. – HLGEM

ответ

1

Here're операторы DDL, выведенные из вашего запроса:

CREATE TABLE users (id integer, username varchar(30)); 
CREATE TABLE boards (id integer, title varchar(30)); 
CREATE TABLE pictures (id integer, link varchar(90)); 
CREATE TABLE boards_pictures (
    id_user integer, 
    id_picture integer, 
    boards_id integer); 
CREATE TABLE followers (id_user integer, id_following integer); 
CREATE TABLE comments (picture_id integer, comment varchar(350)); 

Вы смешивания столбцов именования стилей здесь, сравнение users.id, followers.id_user, comments.picture_id и board_pictures.id_picture (последние 2 достаточно ввести в заблуждение). Чем больше таблиц у вас будет, тем больше внимания вам придется заплатить за то, как назван столбец. Лучше придерживаться единого шаблона, picture_id или user_id наиболее подходящим для меня.

Ваш запрос не является сложным, за исключением того, что вы используете implicit join notation. Это не рекомендуется, так как есть шанс пропустить некоторые предикаты и в итоге получить Cartesian product из 2 (или более) таблиц.

Ваш запрос можно переписать так:

SELECT u.username, p.link, c.comment, b.title 
    FROM boards_pictures bp 
    JOIN pictures p ON p.id = bp.id_picture 
    JOIN followers f ON bp.id_user = f.id_following 
    JOIN users u ON u.id = f.id_following 
    JOIN comments c ON c.picture_id = p.id 
    JOIN boards b ON b.id = bp.boards_id 
WHERE f.id_user = $_session['userid']; 

Как вы видите сейчас, запрос очень прост и имеет только один предикат. Я создал тестовый стенд без данных на SQL Fiddle.

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

1

На самом деле это очень простой запрос, всего несколько таблиц.

Вместо того, чтобы пытаться получить все в одном большом запросе, что приведет к большому количеству дублированных данных в вашем выходе, я бы сделал один запрос, чтобы получить информацию о пользователе/​​доске/картинке, другой запрос для подписчиков и другой запрос для комментариев ,

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

+0

Таким образом, мне нужно сделать один запрос для каждого следующего и одного запроса для комментариев каждого изображения.Итак, если на домашней странице будет показано 50 последних фотографий из моих следующих, то мне нужно сделать 1 запрос, чтобы получить изображения последующих лиц + 50 запросов для получения комментариев к каждой фотографии. – xRobot

+0

нет, вы бы сделали один запрос, который будет получать комментарии для всех 50 изображений – RedFilter

Смежные вопросы