我正在设计一个像 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 )
有没有办法避免这种复杂的查询(包含 6 个表的 JOIN)?
最佳答案
以下是从您的查询中推导出来的 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
(最后两个非常具有误导性)。您拥有的表越多,您就越需要注意列的命名方式。最好坚持单一常见模式,在我看来,picture_id
或 user_id
最合适。
您的查询并不复杂,只是您使用的是 implicit join notation 。这不是推荐的方式,因为有可能会错过一些谓词并最终得到 Cartesian product 2 个(或更多) table 。
您的查询可以这样重写:
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 数据的测试台.
在我看来,你的结构非常好。无需更改表设计或此查询。
关于mysql - 如何避免这种复杂的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10642378/