复制Rails关联是不好的数据设计?

时间:2013-09-20 18:34:41

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

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

user
  belongs_to :group

item
  belongs_to :group
  belongs_to :user

如果未仔细编写代码,则可能导致数据差异:

item.group

item.user.group

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

我的理解是,可能已创建此重复关联以使查询更简单(减少已连接的表的数量)。

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

更新

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

似乎有多种方法可以处理,可能有各种约束,优点,缺点,用例等:

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

我试图了解方法#2和#3之间的差异。在控制台中尝试使用这两种方法后,看起来当调用item.group时由Rails生成的查询会有所不同。 (2)生成一个连接组和用户的单个查询。 (2)产生两个查询,首先找到用户,然后根据用户找到该组。

1 个答案:

答案 0 :(得分:1)

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

如果您希望在查找时获得更快的查询性能,则可以保留额外的关联,并添加额外的before_ *钩子以确保item.group_id = item.user.group_id,并在出现验证错误时他们不匹配。这会使验证/插入稍慢,但会最大化您的数据完整性,并且在从数据库读取时仍然可以获得稍微更好的性能。