Postgres:多对多与多列相对于数组列

时间:2017-04-29 00:03:05

标签: ruby-on-rails postgresql

我需要帮助在Postgres数据库中设计复杂的用户权限。在我的Rails应用程序中,每个用户都可以访问唯一的功能集。换句话说,没有预定义的"角色"确定用户可以访问的功能。

在几乎每个控制器/视图中,应用程序都会检查当前用户是否可以访问不同的功能。理想情况下,该应用程序将提供约100种不同的功能,并将支持500k +用户。

目前,我正在考虑三种不同的选择(但欢迎替代品!),并想知道哪种选择提供最佳性能。 提前感谢您提供任何帮助/建议。

选项1:多对多关系

通过在User表和Feature表之间构建多对多关系,应用程序可以通过查询连接表来检查用户是否可以访问给定功能。

例如,如果连接表中有连接 user1 feature1 的记录,那么 user1 可以访问 feature1

选项2:多列

该应用可以将每个功能表示为User表上的布尔列。这样可以避免查询多个表以检查权限。

例如,如果user1.has_feature1为真,则 user1 可以访问 feature1

选项3:数组列

应用程序可以在User表的(GIN-indexed?)数组列中将功能存储为字符串。然后,要检查用户是否有权访问某个功能,它会在数组列中搜索给定的功能。

例如,如果user1.features.include? 'feature1'为真,则 user1 可以访问 feature1

1 个答案:

答案 0 :(得分:4)

多对多关系是这里唯一可行的选择。他们称之为关系数据库是有原因的。

为什么呢?

  • 加入实际上并不贵。
  • 多列 - 表格中的列数将是ludicris,它将是真正的开发人员地狱。随着每个功能添加迁移,代码库中的流失量将是愚蠢的。
  • 数组列 - 使用数组列可能看起来是一个很有吸引力的选择,直到您意识到它实际上只是将事物填充到逗号分隔字符串中的边际改进。您没有参考完整性,并且没有任何代码组织的好处,因为您的模型代表了应用程序中的实体。
    哦,每次一个功能被猛拉,你必须更新这500k +用户中的每一个。 VS只使用CASCADE。
"errmsg" : "E11000 duplicate key error collection: users.users index: username_1 dup key: { : null }"