【问题标题】:Is it bad data design to duplicate Rails associations?复制 Rails 关联是糟糕的数据设计吗?
【发布时间】:2013-09-20 18:34:40
【问题描述】:

假设我有一个具有以下模型关联的 Rails 3 应用程序:

user
  belongs_to :group

item
  belongs_to :group
  belongs_to :user

如果代码编写不仔细,可能会导致数据不一致,其中:

项目组

item.user.group

当他们应该返回相同的组时,不再返回。一个项目应该始终只属于一个组。

我的理解是,创建这种重复关联可能是为了使查询更简单(减少加入的表的数量)。

所以我的问题是,这只是一个彻头彻尾的糟糕做法,还是一个有效权衡的问题,在某些情况下数据和关联重复是可以接受的,因为我们可以通过更少的连接来简化查询。

更新

到目前为止,答案似乎是“权衡”而不是“不良做法/代码味道”。

似乎有多种处理方式,可能结合了约束、优点、缺点、用例等:

1) 如上所述的非规范化重复数据 2) 项目 has_one :group, :through => :user 3) 项目委托 :group :to => :user

我试图了解方法#2 和#3 之间的区别。在控制台中尝试了这两种方法之后,Rails 在调用 item.group 时产生的查询似乎会有所不同。 (2) 生成连接组和用户的单个查询。 (2) 产生两个查询,首先查找用户,然后根据用户查找组。

【问题讨论】:

  • @BillyChan 为什么问题不能有无效代码甚至根本没有代码?无需代码即可讨论概念。可以就概念提出问题。
  • 本,对不​​起,如果我的话听起来不礼貌。但是你的问题看起来并不那么严重。如果一个项目属于用户,至少用户应该有很多项目?为什么你不能写这个问题?或者这种缺乏另一面也是边缘情况的一部分?为什么不能显示完整的组关联?边缘情况没有错,但最好保持所有其他部分清晰和静止。
  • Billy,我选择添加最少数量的伪代码来理解这个问题。我这样做是因为它减少了其他 stackoverflow 用户的阅读量。我不认为其他协会是相关的。如果用户 has_many items 或 has_one item 与问题无关。这个问题直接关系到是否有重复数据以及因此丢失数据完整性的可能性是一个合理的权衡,如果一个人获得查询性能和更简单的查询。
  • has_one 和 has_many 确实很重要,只是您没有注意到而已。无论如何,我不得不承认我很难理解你的问题以及设计。
  • 如果你能向我解释为什么 has_one 或 has_many 对这个问题很重要,请这样做......你是对的,我不明白为什么它很重要。

标签: sql ruby-on-rails ruby-on-rails-3


【解决方案1】:

我认为这是一个有效权衡的问题。严格来说,在完全规范化的数据库中,您的 items 表不会有 group 列,而是始终通过 users 表来查找 group。这具有最少的重复量,因此具有最高的数据完整性,但代价是每次您想要查找项目的组时都进行额外的连接。我假设一个用户也只属于一个组。如果用户可以属于多个组,那么我认为您必须拥有该 items.group_id 列才能知道项目属于哪些组。

如果您想在查找时获得更快的查询性能,您可以像以前一样保留额外的关联,并添加一个额外的 before_* 挂钩以确保 item.group_id = item.user.group_id,如果出现验证错误,则会引发验证错误他们不匹配。这会使验证/插入稍微慢一些,但会最大限度地提高数据完整性,并且在从数据库读取时仍然可以获得更好的性能。

【讨论】:

  • 谢谢,这正是我正在寻找的那种评论。是的,在这个例子中,一个用户只能属于一个组。
  • 请注意,has_many :through 模式通常适用于这种情况(如果您选择不对数据进行反规范化) - 如果用户 belongs_to 组和项目 belongs_to 用户,您也可以这样说项目has_one :group, :through => :user。然后你可以在一个Item上调用.group,并获取其关联用户的组。
  • @MrTheWalrus:谢谢,这对我提出了一些进一步的问题,编辑原始问题。
猜你喜欢
  • 2011-02-14
  • 1970-01-01
  • 2015-04-22
  • 2012-09-06
  • 2011-08-01
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
相关资源
最近更新 更多