1

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

我的数据库有 3 个表:用户、组和页面

  • 一个用户可以在多个组中
  • 一个组可以有多个用户
  • 一个页面可以有很多组

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

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

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

我的解释的草图:

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

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

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

如果有人可以深入了解什么是最好的,以及我的关系(MtM)是否正确,那就太棒了。

仅供参考:在 Laravel 4 上构建它

谢谢!

4

4 回答 4

3

通常第四范式旨在防止您在单个交集表中存储多个多对多关系。

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

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

于 2013-06-24T20:28:54.153 回答
1

你完成它的方式(在你的第一个图表中)更好,因为你陈述了你的问题。

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

使用第二个图表,您将能够插入没有意义的数据库关系。例如,您的 Link 表可能包含这些行

[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 中的所有行是否有意义。

于 2013-06-24T20:38:59.180 回答
1

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

如果您想描述它user1是您的成员,group1请在第一个双向表中使用它:

user     group
user1    group1

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

user     group    page
user1    group1   page1

这不仅会在user1group1group1和之间创建关联page1,而且还会在user1和之间创建关联page1

同时,您可能会遇到像这样的非常奇怪的情况:

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

请注意,在此示例中,没有user1 group2 page2. 换句话说,仅与throughuser1相关并且仅与through(?!?)相关。我希望很明显这与您最初描述的不符。page1group2user1group2page1

所以我的看法是使用第一个示例中的两个关系表。

于 2013-06-24T20:34:25.803 回答
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 = ?
于 2013-06-24T20:28:17.370 回答