消除Rails中HasMany关系中的连接表

时间:2010-02-20 01:09:06

标签: mysql ruby-on-rails join has-many-through

我正在考虑在Rails中创建基于角色的访问控制系统的方法。我也见过这些伟大的项目(其中包括):

我的问题是,是否真的有必要为所有内容提供连接表?如果我关系中的一个表只有几个值(比如少于100),我不能只将连接表与那个小表合并吗?)这就是我的意思......这就是我需要的:< / p>

模型

  • 用户
  • 作用
  • 权限
  • 的UserRole / RolesUsers
  • GroupRoles
  • 会员资格(GroupUsers)
  • RolePermissions

像这样......

RoleRequirement的工作方式是创建roles表和roles_users联接表。这意味着如果我在应用程序中有20个可能的角色,那么我有

  • 20行的角色表
  • RolesUsers表有n行。

这意味着每次我想按角色查找用户时,我都必须进行加入。我想知道,因为应用程序中只有几个角色,为什么不直接替换这个迁移:

create_table "roles", :force => true do |t|
  t.string "name"
end

create_table "roles_users", :id => false, :force => true do |t|
  t.integer "role_id"
  t.integer "user_id"
end

这一个......

create_table "roles", :force => true do |t|
  t.string "name"
  t.integer "user_id" # or some polymorphic form
end

这会导致重复(例如,大量名为“admin”的角色),但由于空间很便宜,我们可以创建一个像Role.unique这样的方法来查找所有独特的角色(摆脱那个20-行表),为什么人们创建连接表?

与权限相同:我只有4个权限可以启动:create read update delete。所以我不需要权限表和roles_permissions表,我可以只复制CRUD权限并在权限表中使用role_id。与Group相同,如果我的roles表中有多态列,我不需要组角色。

建议的方法是什么?

这是snippet of the proposed migration

1 个答案:

答案 0 :(得分:2)

我不建议你这样做。您描述的内容称为denormalization

非规范化为许多应用程序带来了问题,只有在您有明确的 need 时才应该这样做。我通常只是为了报告目的而对表进行非规范化。

您的问题并未表明您需要进行非规范化。相反,它显示了对“额外”表格的误导性厌恶,并避免了简单的连接。复制数据的成本不仅仅是空间,它还会降低性能(独特的不是免费赠品)。现代RDBMS非常擅长处理连接。

我建议使用Google搜索并搜索SO以获取有关非规范化的信息。没有黄金法则,但你的情况似乎没有任何充分的理由。

如果您正在寻找性能提升,请将ActiveRecord放入垃圾箱。有很多选择,您可以自己编写。