【问题标题】:Simple relational database planning suggestions简单的关系型数据库规划建议
【发布时间】:2013-06-24 20:19:26
【问题描述】:

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

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

  • 一个用户可以属于多个组
  • 一个组可以有很多用户
  • 一个页面可以有多个组

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

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

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

我的解释的草图:

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

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

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

如果有人能对什么是最好的,以及我的关系 (M-t-M) 是否正确提供一些见解,那就太棒了。

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

谢谢!

【问题讨论】:

    标签: mysql database laravel


    【解决方案1】:

    通常Fourth Normal Form 是为了防止您在一个交集表中存储多个多对多关系。

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

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

    【讨论】:

      【解决方案2】:

      由于您陈述问题的方式,您完成它的方式(在您的第一个图表中)更好。

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

      使用您的第二张图表,您将能够在您的数据库关系中插入没有意义的内容。例如,您的 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 中的所有行是否有意义。

      【讨论】:

      • 是的,现在这很有意义,我没有考虑到你描述的整个情况,所以会坚持使用标准化方法。干杯
      【解决方案3】:

      第一种方法(有 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 = ?
      

      【讨论】:

        【解决方案4】:

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

        如果你想描述 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 仅通过 group2page1 相关,而user1 仅通过 (?!?) page1group2 相关。我希望很明显这与您最初描述的不符。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-02
          • 2016-03-21
          • 1970-01-01
          相关资源
          最近更新 更多