我想知道将我的用户及其群组存储在3个表和2个表中的利弊。
2桌的优点
3个表的优点
groups
表将更加明确,因此开发人员可能更容易理解/维护。3个表的缺点 1.通过不执行上面“2个表的优点”中的#1来违反应用程序代码中的DRY原则。
我还应该考虑什么?
2个必填表是users
表和group_member
表。
+---------+ +------------+
| users | | group_member | +----------+
+---------+ +------------+ | groups |
| user_id |----->| user_id | +----------+
| name | | group_id |<----| group_id |
| pass | +------------+ | name |
| ... | | ... |
+---------+ +----------+
**theoretical 3rd table**
注意: user_id
表中的group_id
和group_member
都是
引用user_id
表格中的users
答案 0 :(得分:3)
要点:如果你想存储用户和在一个表中的组共享(大多数)特征,这是完全有效的。 然而,这意味着从技术上讲,一个组可以是一个用户的成员,并且你不能在数据库级别强制执行用户可以成组而不是另一个警惕:
1表中的情景:
CREATE TABLE users_and_groups (id int...
CREATE TABLE group_members (
group_id,
user_id
FOREIGN KEY (group_id) REFERENCES users_and_group (id) -- no way to limit on only groups
FOREIGN KEY (user_id) REFERENCES users_and_group (id) -- no way to limit on only users
)
2个表格中的情景:
CREATE TABLE users (id int...
CREATE TABLE groups (id int...
CREATE TABLE group_members (
group_id,
user_id
FOREIGN KEY (group_id) REFERENCES groups (id) -- guarantees a group
FOREIGN KEY (user_id) REFERENCES users (id) -- guarantees a user
)
如果出现应用程序级别的错误,那么像防范这样设置数据库可以防止大量的伤害。
但是,user
&amp; group
个实体共享 lot 数据(例如,它们可以拥有其他对象,拥有个人资料页面等),4表解决方案可以很好地运行:
CREATE TABLE users_and_groups (id, ...shared data...
CREATE TABLE users (users_and_groups_id, ...user specific data...
CREATE TABLE groups (users_and_groups_id, .. group specific data...
CREATE TABLE group_members (
group_id,
user_id
FOREIGN KEY (group_id) REFERENCES groups (users_and_groups_id) -- guarantees a group
FOREIGN KEY (user_id) REFERENCES users (users_and_groups_id) -- guarantees a user
)
这有几个好处:
users_and_groups
,以及user
和&amp; group
扩展该基类/表。一些缺点:
type
(或is_group
/ is_user
),否则确定实体是组还是用户需要JOIN
,但是在两边的主键上,开销应该很小答案 1 :(得分:2)
如果有的话,我认为group_member
将是可选表。如果用户和组之间需要多对多关系,则仅需要此表。换句话说,如果用户可以属于多个组,则您需要一个可以将user_id
链接到group_id
的表格。如果用户只能属于一个组,您可能仍然想要一个groups
表,然后拥有一个{ group_id
表格上的{1}}列。
但是,要回答原始问题,如果您将组信息(例如组名称)存储在users
表中,则必须为组内的每个用户重复此数据。您有许多具有相同组名的行,如果您希望以后更改组名称,则必须更新许多行而不是一行。它也很难说出同一组中的谁,并且很多这类查询会变得非常低效。
将不同的组规范化为单个group_member
表绝对是正确的方法,无论您使用一个还是两个表。