【问题标题】:Postgres: Many-to-many vs. multiple columns vs. array columnPostgres:多对多与多列与数组列
【发布时间】:2017-04-29 00:03:04
【问题描述】:

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

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

目前,我正在考虑三种不同的选项(但欢迎使用其他选项!)并且想知道哪个选项提供最佳性能。 提前感谢您的任何帮助/建议。

选项 1:多对多关系

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

例如,如果连接表中有一条记录连接 user1feature1,则 user1 可以访问 feature1 .

选项 2:多列

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

例如,如果 user1.has_feature1 为真,则 user1 有权访问 feature1

选项 3:数组列

该应用可以将特征作为字符串存储在User 表的(GIN 索引?)数组列中。然后,为了检查用户是否可以访问某个功能,它会在数组列中搜索给定的功能。

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

【问题讨论】:

  • 我很想使用多对多 (#1) 作为事实来源(即管理用户特征关联的所有管理表单),然后非规范化(通过回调? ) 到用户 (#3) 的数组列,当该用户登录时,您只需检查数组的访问权限。我认为您可以对该列使用 rails serialize :features, Array,在数据库级别没有什么特别需要的,因为您从未真正查询过该列。
  • since you never actually query that column 似乎是一个错误的假设。

标签: ruby-on-rails postgresql


【解决方案1】:

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

为什么?

  • 联接实际上并不昂贵。
  • 多列 - 表中的列数将是可笑的,这将是真正的开发人员地狱。由于每个功能都添加了迁移,因此代码库中的流失量将是愚蠢的。
  • 数组列 - 使用数组列似乎是一种有吸引力的替代方案,直到您意识到它实际上只是将内容填充到逗号分隔字符串中的边际改进。您没有参照完整性,并且没有任何代码组织的好处来自拥有代表应用程序中实体的模型。
    哦,每次拉出一项功能时,您都必须更新这 500k+ 用户中的每一个。 VS 只使用 CASCADE。

class Feature
  has_many :user_features
  has_many :users, through: :user_features
end

class UserFeature
  belongs_to :user
  belongs_to :feature
end

class User
  has_many :user_features
  has_many :features, through: :user_features

  def has_feature?(name)
    features.exist?(name: name)
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-06
    • 2021-07-19
    • 1970-01-01
    • 2014-04-29
    • 1970-01-01
    • 2023-03-16
    • 2011-08-24
    • 2020-11-10
    相关资源
    最近更新 更多