更好的数据库设计

时间:2011-06-28 05:33:11

标签: mysql ruby-on-rails database database-design scalability

我们有像所有者,编辑,观众等角色...... 每个角色都有不同的权限,如下载,共享,编辑,查看等...

我为此功能创建了两个数据库设计。我必须实现哪种数据库设计?

1) Table   -> Roles 
   Columns -> Id
              Name
              isDownload
              isShare
              isView

2) Table   -> Roles
   Column  -> Id
              Name
              Description

   Table   -> Privileges
   Column  -> Id 
              Name
              Description

   Table   -> RolesPrivileges
   Column  -> Id
              RoleId
              PrivilegeId

这些设计的优点和缺点是什么?我要实施哪一个? 哪个更具可扩展性和可维护性?为什么?

5 个答案:

答案 0 :(得分:2)

第二个是要走的路。 如果需要创建新角色,则不必修改表结构,只需创建新角色,并关联privlidges等。 第一个设计的最大问题是角色/ privlidges的任何变化都需要对表结构进行更改。

答案 1 :(得分:1)

这样的事情很大程度上取决于你的数据库将如何使用 - 例如:

  1. 灵活性 - 您可能需要在将来添加其他角色/权限吗?如果是这样,请在#2中使用更具扩展性和灵活性的表结构。
  2. 复杂性 - 如果您的数据库比休闲小型系统大,我建议您选择#2。但是,如果它非常小并且非正式使用,可能值得您节省时间来使用更简单的系统。
  3. 性能 - #2显然更复杂,可能需要更多查询,尤其是如果您遇到任何可能需要同时执行多项操作的情况。但是,通过正确使用数据库索引可以很好地减轻这种情况。

答案 2 :(得分:0)

1) Table   -> Roles 
   Columns -> Id
              Name
              Description
              isDownload
              isShare
              isView


2) Table   -> UserRolesPrivileges
   Column  -> Id
              RoleId
              UserId

UserId来自用户注册表。

每个用户都与相应的角色相关联  在角色表中,我认为您将拥有不同的角色,每个角色都将扮演不同的角色  定义了它可以执行的操作。

我没有看到任何Privileges表的使用,只要用户与角色相关联

答案 3 :(得分:0)

我想对备选方案1提出建议,这可能会使一些批评措辞无法实现。不是为每个可能的权限使用布尔值,而是使用位掩码。

首先是一个例子

(responsible_mask INT)

def Roles

    RESPONSIBILITES = [ :switchboard, :content_manager, :network_administrator, :financial_manager, :receives_contact_emails ]

    def responsibilites=(responsibilites)
        self.responsible_mask = ([*responsibilites].map(&:to_sym) & RESPONSIBILITES).map { |r| 2**RESPONSIBILITES.index(r) }.sum
    end

    def responsibilites
        RESPONSIBILITES.reject { |r| ((responsible_mask || 0) & 2**RESPONSIBILITES.index(r)).zero? }
    end

    def responsibilites_symbols
        responsibilites.map(&:to_sym)
    end

    def responsible?(responsibility="none")
        responsibilities_symbols.includes?(responsibility.to_sym)
    end
end

随时都可以轻松添加更多职责。

现在为什么?

在我看来,这是更好的做法。我无法看到为什么我会创建一个表单来添加另一个责任(或者你的情况下的特权)而不在我的代码中放置钩子以使用该责任的原因。我只需要这些信息来确定我是否应该允许功能;它没有其他目的。当然,我仍然希望管理员能够创建角色并为该角色分配职责,但它始终是固定集。

它还使SQL查询更加复杂 - 添加另一个连接。慢点。更难调试。

记住在部署到另一台服务器时构建此静态数据表是一件痛苦的事。

答案 4 :(得分:0)

当然,第一个是实现目标的方法:

Table   -> Roles 
Columns -> Id
           Name
           isDownload
           isShare
           isView
  • 是一个简单的设计
  • 您可以在不需要JOIN的情况下从同一个表中读取角色和权限
  • 的空间要求低于第二种选择

但是,如果您拥有经常添加或删除权限的动态权限,您可能会想到方法2.但是保留单个表是正常的。