简单的关系数据库规划建议

时间:2013-06-24 20:19:26

标签: mysql database laravel

我正在创建一个简单的应用程序,用户通过OAuth系统登录,并将其用户ID存储在会话中。

我的数据库有3个表:User,Group&页

  • 用户可以在多个群组中
  • 一个群组可以拥有多个用户
  • 一个页面可以包含多个组

所以基本上在我的设置区域:

  • 可以将用户分配到组
  • 可以将这些组添加到页面以允许访问

然后,我可以使用用户的ID,查找他们所在的组,然后选择他们有权访问的页面ID。然而,这种方法看起来很长,并且我认为会涉及很多循环(同时,我想我会得到许多相同的页面ID?)。

草拟我的解释:

http://i.imgur.com/oFVsniH.png

我确实感觉有更好的方法来实现这一点 - 使用一个“pivot”表和3个表......类似于:

http://i.imgur.com/IZfhZO1.jpg

如果有人可以提供一些最好的信息,以及我的关系(M-t-M)是否正确,那就太棒了。

仅供参考:在Laravel 4上构建

谢谢!

4 个答案:

答案 0 :(得分:3)

通常Fourth Normal Form旨在阻止您在单个交叉表中存储多个多对多关系。

在这种情况下,您将页面的访问权限授予组,而不是用户。因此,我不会将该页面的引用存储在记录组中用户成员资格的同一个表中。

例如,假设您在一个组中有1000个用户,该组可以访问1个页面。但是在你的第二个设计中,你必须将该组对1000页的访问权限存储起来。

答案 1 :(得分:1)

第一种方法(有5个表)更加规范化。我建议坚持使用它,除非你有一个特定的理由去反规范化。

以下SQL将获取给定用户的所有不同页面ID:

select DISTINCT GP.page_id
from GroupUser GU
join GroupPage GP on GU.group_id = GP.group_id 
where GU.user_id = ?

答案 2 :(得分:1)

三向关系表意味着与两个双向关系表完全不同,因为它将三个实体连接在一起。

如果你想描述user1group1的成员,你可以在第一个双向表中使用它:

user     group
user1    group1

但是扩展另一个字段和页面会改变含义:

user     group    page
user1    group1   page1

这不仅会在user1group1group1page1之间创建关联,还会在user1page1之间建立关联。

与此同时,你可能会遇到这样的奇怪情况:

user     group    page
user1    group1   page1
user1    group1   page2
user1    group2   page1

请注意,在此示例中,没有user1 group2 page2行。换句话说,user1仅通过page1group2相关,user1仅与group2到(?!?)page1相关。我希望很明显,这与你刚才描述的内容不符。

所以我的观点是第一个例子中的两个关系表。

答案 3 :(得分:1)

你所做的方式(在你的第一张图中)更好,因为你已经说明了你的问题。

用户属于组,页面权限映射到组。页面和用户之间没有直接关系(即,您不能将权限直接分配给用户,而只能分配给用户所属的组)。如果以上是您正在尝试做的正确描述,则第一个图表是设计数据库的最规范化方式。

使用第二个图表,您可以在数据库关系中插入无意义的内容。例如,您的链接表可以包含这些行

[user.id=1, group.id=1, page.id=1] 
[user.id=1, group.id=2, page.id=2]
[user.id=2, group.id=2, page.id=1]

现在,通过这些行,组2可以访问第1页和第2页(第2行和第3行)。但是用户2属于组2,只能访问第1页(第3行)。 您仍然可以使这项工作,但您需要从您的应用程序控制Link中的所有行都有意义。