2

这是一个人为的例子,假设我想列出一个人有朋友的国家的人口,下面是两个设置。最好在模型中重复数据吗?

有人告诉我,遵循 得墨忒耳法则很重要,例如你告诉狗走路,命令他的腿走路是愚蠢的。

在我的大量经验不足(菜鸟)中,我发现当模型重复数据时,查询会更容易做People.where(:country => friend.country),vs 有链式关联的集合(到目前为止这是不可能的):(People.where(:city => { :county => { :region => { :country => friend.city.county.region.country }}}) 这真的会帮助这个菜鸟如果您能想象正确的人为设计的 LoD 设置和语法,请在这里理解这个概念,我真的希望我没有使用与得墨忒耳定律无关的示例)我尝试通过应用 LoDdelegate并被告知我是仍然链接(我是),我能想到的唯一解决方案是重复可以通过关联访问的数据。

但我讨厌重复数据!这是由于遵循了 DHH 的 Rails 教程,我们在其中重新创建了 twitter,他展示了创建关系与重复数据是多么棒。

重复数据是否适合减少关联的链接?

模型,重复数据

class Country < ActiveRecord::Base    
  has_many :regions    
  has_many :counties    
  has_many :cities    
  has_many :people
end

class Region < ActiveRecord::Base
  has_one :country
  has_many :counties
  has_many :cities    
  has_many :people
end

class County < ActiveRecord::Base
  has_one :country
  has_one :region
  has_many :cities    
  has_many :people
end

class City < ActiveRecord::Base
  has_one :country
  has_one :region
  has_one :county    
  has_many :people
end

class Person < ActiveRecord::Base
  has_one :country
  has_one :region
  has_one :county    
  has_one :city
  has_many :relationships
  has_many :friends, :through => :relationships
end

vs 具有链式关联的模型

class Country < ActiveRecord::Base    
  has_many :regions   
end

class Region < ActiveRecord::Base
  belongs_to :country
  has_many :counties
end

class County < ActiveRecord::Base
  belongs_to :region
  has_many :cities
end

class City < ActiveRecord::Base
  belongs_to :county
end

class Person < ActiveRecord::Base
  belongs_to :city
end
4

3 回答 3

1

这似乎不是德米特法则的问题,而是数据库设计和数据完整性的问题。第一个选项应该被排除,因为它创建了一个绝对违反第三范式(3NF)的数据库:

在您的第一个示例中,如果某个国家/地区 HM 城市,如果您将该城市更新为属于不再属于该国家/地区的不同区域,会发生什么情况?-> 砰!数据完整性消失了!当然,一个城市不太可能搬到另一个国家,但就像你说的,这是一个人为的例子,我说的是一般情况

你应该谷歌数据库规范化和第三范式以获得更多信息。

此外,在这种情况下,您违反 3NF 只是因为您认为这样做可以“提高性能”。这是预优化的一个案例,也是一种不好的做法。虽然在某些情况下,去规范化是一种可控的风险,但这里是龙,如果你只是在 Rails 中启动一个应用程序,绝对不是这种情况。让您的数据库担心快速获取数据。您可以通过提供良好的索引来帮助它。

另外,我认为您正在寻找的是一种创建嵌套关系的方法。你希望它是这样的情况:

一个国家 HM 县通过地区

然后,

一个国家 HM Cities THROUGH Counties

如果您使用的是 3.0,这将是 3.1 中的标准,那么您可以使用

https://github.com/ianwhite/nested_has_many_through

gem,我目前正在使用,并且非常满意。

于 2011-06-19T18:55:45.050 回答
1

啊,“得墨忒耳偶尔有用的建议”。(马丁·福勒。)

我认为 DIE/DRY 和规范化是更基本的原则,但最终将是您需要应用常识的相互冲突的准则之间的竞争。

该“定律”适用于特定项目中的对象类,并且作为类层次设计模型具有明显的价值。

但是对于Demeter 的应用程序,特别是在 Rails 视图方面存在争议。根据定义,它们是一份报告,因此德米特的建议是否适用是值得怀疑的。

于 2011-06-19T18:59:16.170 回答
0

在我看来,您应该尽可能避免重复数据。但是,您可以创建允许您组合数据的聚合对象。所以你可以保持你的核心实体干净,但然后有额外的支持实体来聚合对象。

如果您使用 SQL 中的视图示例,您可以检索到由许多实体组合而成的结果。该结果可能是聚合实体,并且是“重复”数据的完全合法手段。

于 2011-06-19T18:53:45.480 回答