如果访问数据库的方法与两个或多个表交互,如何决定在哪里存储该方法?

问题描述 投票:0回答:1

我是编码训练营的初学者,我正在学习使用 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);

python oop flask database-design repository-pattern
1个回答
0
投票

这些似乎是非常适合帖子实体的方法,因为您可以缓存找到的内容并重用帖子的点赞和评论。

假设您有一个帖子,其 id 为 123。我们进一步假设您需要获取该帖子的评论和点赞 10 次。如果您不小心的话,就会向数据库发出 20 个又长又昂贵的请求。相反,您可以实现此模式:

  • 如果要搜索的评论/点赞已经针对该帖子进行了计算,那么
    • 从缓存中读取它们
  • 否则
    • 从数据库中读取它们
    • 将它们写入该对象的缓存中

评论/点赞的缓存将是评论的集合,另一个是每个帖子点赞的缓存。当您阅读帖子的评论时,您的代码需要检查它们是否已经被计算。如果是这样,则从缓存中读取结果,而不是在数据库中重新搜索它们。对于喜欢,同样的原则也成立。

© www.soinside.com 2019 - 2024. All rights reserved.