数据库设计-正确使用三个表之间的多对多关系?
Database design- Correct usage of many-to-many relationships between three tables?
上下文
我有三个 table、Users
、Subreddits
和 Keywords
。思路是users
可以监控多个subreddits
,subreddits
可以跟踪多个keywords
.
因为一个用户可以监控多个subreddit,一个subreddit可以有多个用户监控,我在Users
和Subreddits
之间使用了多对多的关系。
同理,由于一个subreddit可以追踪多个关键词,一个关键词可以被多个subreddit追踪,所以我在Subreddits
和[=15=之间使用了多对多的关系].
实施
以下是我如何实现每个 table 以及它们的多对多关系:
用户
users_subreddits = db.Table('users_subreddits',
db.Column('user_id', db.Integer, db.ForeignKey('users.id', ondelete='CASCADE')),
db.Column('subreddit_id', db.Integer, db.ForeignKey('subreddits.id', ondelete='CASCADE'))
)
class User(db.Model, JsonSerializer):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(128), index=True, unique=True)
password_hash = db.Column(db.String(128))
phone_num = db.Column(db.String(64), index=True, unique=True)
received_posts = db.Column(db.String(128), index=True, unique=True)
subreddits = db.relationship('Subreddit', secondary=users_subreddits, backref='users', lazy='dynamic')
//...
子版块
subreddits_keywords = db.Table('subreddits_keywords', db.Model.metadata,
db.Column('subreddit_id', db.Integer, db.ForeignKey('subreddits.id', ondelete='CASCADE')),
db.Column('keyword_id', db.Integer, db.ForeignKey('keywords.id', ondelete='CASCADE')),
)
class Subreddit(db.Model, JsonSerializer):
__tablename__ = 'subreddits'
id = db.Column(db.Integer, primary_key=True)
subreddit_name = db.Column(db.String(128), index=True)
keywords = db.relationship('Keyword', secondary=subreddits_keywords, backref='subreddits', lazy='dynamic')
// ...
关键词
class Keyword(db.Model, JsonSerializer):
"""
The keywords table.
"""
__tablename__ = 'keywords'
id = db.Column(db.Integer, primary_key=True)
keyword = db.Column(db.String(128), index=True)
问题
因为我想跟踪各个用户如何监控他们的 subreddit 和关键字,我将 Keywords
附加到 Subreddits
,每个 Subreddit 附加到 Users
。
例如,
user1
监控 subreddit1
,它正在跟踪 keyword1
和 keyword2
。
keyword1
和 keyword2
附加到 subreddit1
。
subreddit1
附加到 user1
。
问题来了。由于我使用的是多对多关系,因此我希望每个 table 中的所有数据都是唯一的。 这是个坏主意吗?
为了说明我的意思,请考虑以下内容:
user1
监控 subreddit1
,它正在跟踪 keyword1
和 keyword2
。
user2
监控 subreddit1
,它正在跟踪 keyword3
。
由于subreddit1
在数据库中是唯一的,keyword1
和keyword2
被user1追加到subreddit1
,但是keyword3
也被追加到subreddit1
由 user2.
这意味着 subreddit1
正在跟踪 keyword1
、keyword2
和 keyword3
。当 user2
仅监视 keyword3
的 subreddit1
时,这是一个问题。
Is a many-to-many relationship here a bad idea?
我考虑过的解决方案
我可以为每个用户保留 subreddit1
的不同实例。这些 subreddit1
中的每一个都会跟踪各自的关键字。
结果将是:
user1
监控 subreddit1
,它正在跟踪 keyword1
和 keyword2
。
user2
监控 subreddit1
,它正在跟踪 keyword3
。
因为有2个subreddit1
,所以user1
的subreddit1
追加了keyword1
和keyword2
,而user2
' s subreddit1
附加 keyword3
.
If I use this approach, what is the point of using a many-to-many relationship? Is there an alternative I can use?
我认为多对多关系的意义在于 Subreddits
中的每个条目都可以与不同的用户和不同的关键字相关,而无需创建重复的条目。
由于您的设计有效地允许用户、subreddit 和关键字的任意组合(这本身并没有错),那么一个解决方案是创建一个“监控”table 来保存 3 tables 并记录每个允许的组合 user/subreddit/keyword。实际上,您正在创建一个链接 3 table 而不仅仅是 2
的多对多 table
上下文
我有三个 table、Users
、Subreddits
和 Keywords
。思路是users
可以监控多个subreddits
,subreddits
可以跟踪多个keywords
.
因为一个用户可以监控多个subreddit,一个subreddit可以有多个用户监控,我在Users
和Subreddits
之间使用了多对多的关系。
同理,由于一个subreddit可以追踪多个关键词,一个关键词可以被多个subreddit追踪,所以我在Subreddits
和[=15=之间使用了多对多的关系].
实施
以下是我如何实现每个 table 以及它们的多对多关系:
用户
users_subreddits = db.Table('users_subreddits',
db.Column('user_id', db.Integer, db.ForeignKey('users.id', ondelete='CASCADE')),
db.Column('subreddit_id', db.Integer, db.ForeignKey('subreddits.id', ondelete='CASCADE'))
)
class User(db.Model, JsonSerializer):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(128), index=True, unique=True)
password_hash = db.Column(db.String(128))
phone_num = db.Column(db.String(64), index=True, unique=True)
received_posts = db.Column(db.String(128), index=True, unique=True)
subreddits = db.relationship('Subreddit', secondary=users_subreddits, backref='users', lazy='dynamic')
//...
子版块
subreddits_keywords = db.Table('subreddits_keywords', db.Model.metadata,
db.Column('subreddit_id', db.Integer, db.ForeignKey('subreddits.id', ondelete='CASCADE')),
db.Column('keyword_id', db.Integer, db.ForeignKey('keywords.id', ondelete='CASCADE')),
)
class Subreddit(db.Model, JsonSerializer):
__tablename__ = 'subreddits'
id = db.Column(db.Integer, primary_key=True)
subreddit_name = db.Column(db.String(128), index=True)
keywords = db.relationship('Keyword', secondary=subreddits_keywords, backref='subreddits', lazy='dynamic')
// ...
关键词
class Keyword(db.Model, JsonSerializer):
"""
The keywords table.
"""
__tablename__ = 'keywords'
id = db.Column(db.Integer, primary_key=True)
keyword = db.Column(db.String(128), index=True)
问题
因为我想跟踪各个用户如何监控他们的 subreddit 和关键字,我将 Keywords
附加到 Subreddits
,每个 Subreddit 附加到 Users
。
例如,
user1
监控subreddit1
,它正在跟踪keyword1
和keyword2
。keyword1
和keyword2
附加到subreddit1
。subreddit1
附加到user1
。
问题来了。由于我使用的是多对多关系,因此我希望每个 table 中的所有数据都是唯一的。 这是个坏主意吗?
为了说明我的意思,请考虑以下内容:
user1
监控subreddit1
,它正在跟踪keyword1
和keyword2
。user2
监控subreddit1
,它正在跟踪keyword3
。
由于subreddit1
在数据库中是唯一的,keyword1
和keyword2
被user1追加到subreddit1
,但是keyword3
也被追加到subreddit1
由 user2.
这意味着 subreddit1
正在跟踪 keyword1
、keyword2
和 keyword3
。当 user2
仅监视 keyword3
的 subreddit1
时,这是一个问题。
Is a many-to-many relationship here a bad idea?
我考虑过的解决方案
我可以为每个用户保留 subreddit1
的不同实例。这些 subreddit1
中的每一个都会跟踪各自的关键字。
结果将是:
user1
监控subreddit1
,它正在跟踪keyword1
和keyword2
。user2
监控subreddit1
,它正在跟踪keyword3
。
因为有2个subreddit1
,所以user1
的subreddit1
追加了keyword1
和keyword2
,而user2
' s subreddit1
附加 keyword3
.
If I use this approach, what is the point of using a many-to-many relationship? Is there an alternative I can use?
我认为多对多关系的意义在于 Subreddits
中的每个条目都可以与不同的用户和不同的关键字相关,而无需创建重复的条目。
由于您的设计有效地允许用户、subreddit 和关键字的任意组合(这本身并没有错),那么一个解决方案是创建一个“监控”table 来保存 3 tables 并记录每个允许的组合 user/subreddit/keyword。实际上,您正在创建一个链接 3 table 而不仅仅是 2
的多对多 table