类似 Twitter 的帖子时间线的数据库结构和查询

Sim*_*ger 4 sql database django postgresql

我用 Django 标签发布这个问题,因为我在这个环境中工作,但这实际上更多的是一个通用问题:我想在 Twitter 上显示类似我的时间线的内容,即所有帖子的列表我关注的人按时间顺序排列。

我的典型数据库结构如下所示:

Table Name: Users
Columns:
    UserID PK
    EmailAddress
    Password

TableName: Friends
Columns:
    UserID PK FK
    FriendID PK FK

TableName: Posts
Columns:
    UserID PK FK
    Content
Run Code Online (Sandbox Code Playgroud)

如果我想检索给定用户的所有朋友的所有帖子,它看起来像这样(这不应该是有效的 SQL!):

SELECT * FROM Posts WHERE UserID IN (LIST OF "Given user friends' IDs")
Run Code Online (Sandbox Code Playgroud)

这有效 - 没问题!然而,这并不能扩展!假设我们有一个繁忙的网站,给定的用户有 2,000 个朋友,数据库中有大约一千万个帖子。在这种情况下,数据库查询将非常低效且缓慢。

可以使用 PostgreSQL 或 MySQL 等关系数据库来解决这个问题吗?如果没有,Twitter 是如何做到的?

joa*_*olo 5

较短的版本:

SELECT
    Posts.*
FROM
    Posts 
    JOIN Friends ON Friends.FriendID = Posts.UserID
WHERE
    Friends.UserID = 1 /* change as needed */ ;
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式检查:

CREATE TABLE Users
(
    UserID integer PRIMARY KEY,
    EmailAddress text,
    Password text
) ;

CREATE TABLE Friends
(
    UserID integer NOT NULL REFERENCES Users(UserID),
    FriendID integer NOT NULL REFERENCES Users(UserID),
    PRIMARY KEY (UserID, FriendID)
) ;

CREATE TABLE Posts
(
    PostID integer PRIMARY KEY,
    UserID integer NOT NULL REFERENCES Users(UserID),
    Content text
) ;

INSERT INTO Users 
VALUES 
  (1, 'a@b.com', 'pass1'),
  (2, 'b@b.com', 'pass2'),
  (3, 'c@b.com', 'pass3'),
  (4, 'd@b.com', 'pass4') ;

INSERT INTO Friends
VALUES 
   (1, 2),
   (1, 4) ;

INSERT INTO Posts
VALUES
    (1, 2, 'A post from User 2'),
    (2, 2, 'Another post from User 2'),
    (3, 3, 'A post from User 3'),
    (4, 4, 'A post from User 4') ;
Run Code Online (Sandbox Code Playgroud)

你应该得到:

+---+---+--------------------------+
| 1 | 2 | A post from User 2       |
| 2 | 2 | Another post from User 2 |
| 4 | 4 | A post from User 4       |
+---+---+--------------------------+
Run Code Online (Sandbox Code Playgroud)