我正在创建一个简单的应用程序,用户通过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上构建
谢谢!
答案 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)
三向关系表意味着与两个双向关系表完全不同,因为它将三个实体连接在一起。
如果你想描述user1
是group1
的成员,你可以在第一个双向表中使用它:
user group
user1 group1
但是扩展另一个字段和页面会改变含义:
user group page
user1 group1 page1
这不仅会在user1
和group1
,group1
和page1
之间创建关联,还会在user1
和page1
之间建立关联。
与此同时,你可能会遇到这样的奇怪情况:
user group page
user1 group1 page1
user1 group1 page2
user1 group2 page1
请注意,在此示例中,没有user1 group2 page2
行。换句话说,user1
仅通过page1
与group2
相关,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中的所有行都有意义。