我是编码训练营的初学者,我正在学习使用 Flask、Python、PostgresQL 和 psycopg 从头开始制作 CRUD 应用程序。我正在尝试为 Twitter 克隆创建后端,其中包含用户、帖子、评论、关注、喜欢和主题标签。为此,我为每个元素创建一个模型类和存储库类。我在下面附上了我的 ER 图和种子 SQL 查询。
我想知道作为一个一般问题,您如何决定在哪里存储两个或多个元素之间交互的方法?例如,我想要以下方法,其中
posts
与 likes
和 comments
交互,其中 posts
与每个 likes
和 comments
具有一对多关系,我有以下猜测:
.sort_posts_by_likes()
-- post_repository.get_all_likes_for_post(post_id)
-- like_repository.get_all_comments_for_post(post_id)
——comment_repository
我的总体想法是将方法存储在关系的“多”方,因为我觉得存储库类管理相关元素的group
下面的数据库种子
CREATE SEQUENCE IF NOT EXISTS users_id_seq;
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255),
password VARCHAR(255),
handle VARCHAR(255),
name VARCHAR(255),
joined_on TIMESTAMP
);
CREATE SEQUENCE IF NOT EXISTS posts_id_seq;
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
user_id INTEGER,
content VARCHAR(255),
created_on TIMESTAMP
-- CONSTRAINT fk_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE SEQUENCE IF NOT EXISTS comments_id_seq;
CREATE TABLE comments (
id SERIAL PRIMARY KEY,
user_id INTEGER,
post_id INTEGER,
content VARCHAR(255),
created_on TIMESTAMP
-- CONSTRAINT fk_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
-- CONSTRAINT fk_posts FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE
);
CREATE SEQUENCE IF NOT EXISTS hashtags_id_seq;
CREATE TABLE hashtags (
id SERIAL PRIMARY KEY,
title VARCHAR(255)
);
-- Join tables
CREATE SEQUENCE IF NOT EXISTS follows_id_seq;
CREATE TABLE follows (
id SERIAL PRIMARY KEY,
follower_id INTEGER,
followee_id INTEGER
-- CONSTRAINT fk_users FOREIGN KEY (follower_id) REFERENCES users(id) ON DELETE CASCADE,
-- CONSTRAINT fk_users FOREIGN KEY (followee_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE SEQUENCE IF NOT EXISTS likes_id_seq;
CREATE TABLE likes (
id SERIAL PRIMARY KEY,
user_id INTEGER,
post_id INTEGER NULL, -- can be blank
comment_id INTEGER NULL -- can be blank
-- CONSTRAINT fk_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
-- CONSTRAINT fk_posts FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
-- CONSTRAINT fk_comments FOREIGN KEY (comment_id) REFERENCES comments(id) ON DELETE CASCADE
);
CREATE SEQUENCE IF NOT EXISTS hashtags_posts_id_sequence;
CREATE TABLE hashtags_posts (
id SERIAL PRIMARY KEY,
hashtag_id INTEGER,
post_id INTEGER
-- CONSTRAINT fk_hashtag FOREIGN KEY (hashtag_id) REFERENCES hashtags(id) ON DELETE CASCADE,
-- CONSTRAINT fk_posts FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE
);
-- Then we inject some test data: ------------
-- CREATING USERS:
-- Creating 3 test users
INSERT INTO users (email, password, handle, name, joined_on) VALUES ('[email protected]', 'davidBeckam00@', 'FIFAcom', 'FIFA', '2015-07-28');
INSERT INTO users (email, password, handle, name, joined_on) VALUES ('[email protected]', 'feeltheBern12#', 'BernieSanders', 'Bernie Sanders', '2013-09-22');
INSERT INTO users (email, password, handle, name, joined_on) VALUES ('[email protected]', '1234567890a0C', 'AOC', 'Alexandria Ocasio-Cortez', '2017-06-01');
-- CREATE HASHTAGS:
-- Creating 3 hashtags
INSERT INTO hashtags (title) VALUES ('football');
INSERT INTO hashtags (title) VALUES ('memes');
INSERT INTO hashtags (title) VALUES ('shows');
-- MAKING POSTS:
-- User 1 makes Post 1 with Hashtag 1 and 3
INSERT INTO posts (user_id, content, created_on) VALUES (1, 'Has anyone seen the new David Beckham series?', '2023-10-16 12:30:00');
INSERT INTO hashtags_posts (hashtag_id, post_id) VALUES (3, 1);
INSERT INTO hashtags_posts (hashtag_id, post_id) VALUES (1, 1);
-- User 1 makes Post 2 with Hashtag 1, 2
INSERT INTO posts (user_id, content, created_on) VALUES (1, '"football" not "soccer", tyvm', '2023-10-17 10:30:00');
INSERT INTO hashtags_posts (hashtag_id, post_id) VALUES (1, 2);
INSERT INTO hashtags_posts (hashtag_id, post_id) VALUES (2, 2);
-- User 2 makes Post 3 with Hashtags 1
INSERT INTO posts (user_id, content, created_on) VALUES (2, 'I am once again asking for your financial support', '2023-10-17 11:09:00');
INSERT INTO hashtags_posts (hashtag_id, post_id) VALUES (2, 3);
-- COMMENTING POSTS:
-- User 2 makes Comment 1 - Post 1
INSERT INTO comments (user_id, post_id, content, created_on) VALUES (2, 1, 'Yes it was sooo good!', '2023-10-16 19:05:00');
-- User 3 makes Comment 2 - Post 1
INSERT INTO comments (user_id, post_id, content, created_on) VALUES (3, 1, 'the scene where david asked posh about her dads car lollll', '2023-10-16 23:15:00');
-- User 3 makes Comment 3 - Post 2
INSERT INTO comments (user_id, post_id, content, created_on) VALUES (3, 2, 'classic', '2023-10-17 13:47:00');
-- LIKING POSTS & COMMENTS:
-- User 3 likes Post 1, 2
INSERT INTO likes (user_id, post_id) VALUES (3, 1);
-- User 2, 3 like Post 2
INSERT INTO likes (user_id, post_id) VALUES (2, 2);
INSERT INTO likes (user_id, post_id) VALUES (3, 2);
-- User 3 likes Post 3
INSERT INTO likes (user_id, post_id) VALUES (3, 3);
-- User 2 likes Comment 3
INSERT INTO likes (user_id, comment_id) VALUES (2, 3);
-- FOLLOWING:
-- User 3 follows User 1 and 2
INSERT INTO follows (follower_id, followee_id) VALUES (3, 1);
INSERT INTO follows (follower_id, followee_id) VALUES (3, 2);
-- User 2 follows User 3
INSERT INTO follows (follower_id, followee_id) VALUES (2, 3);
这些似乎是非常适合帖子实体的方法,因为您可以缓存找到的内容并重用帖子的点赞和评论。
假设您有一个帖子,其 id 为 123。我们进一步假设您需要获取该帖子的评论和点赞 10 次。如果您不小心的话,就会向数据库发出 20 个又长又昂贵的请求。相反,您可以实现此模式:
评论/点赞的缓存将是评论的集合,另一个是每个帖子点赞的缓存。当您阅读帖子的评论时,您的代码需要检查它们是否已经被计算。如果是这样,则从缓存中读取结果,而不是在数据库中重新搜索它们。对于喜欢,同样的原则也成立。