目前我有一个详细说明两个人之间关系的模型。
即:
Relationship
t.references :person_one
t.references :person_two
当其中一个人查看关系时,他们会看到对方的名字。从时间角度来看,仅存储引用是否更有意义?或者做这样的事情更有意义:
Relationship
t.string :person_one
t.string :person_two
每个人也能够查看他们所属的所有关系。即每个人都有很多关系。
似乎t.references只是一种抽象添加person_id列的方法,但它返回所需的Person对象,而不是id。我绝对可以看到每个人的利弊。在前者中,似乎使用person.relationships来获取所有单个人的关系可能更容易(代码方面),但似乎在该实现下似乎发生了许多幕后查询。我感兴趣的是优化时间复杂度/减少我必须通过SQL数据库的次数。但我可能误解了Rails存储然后检索这些数据的确切方式。
思想?
答案 0 :(得分:1)
很可能是你的"额外的查询"是由于加载您的关系所需的N + 1个查询。您应该研究ActiveRecord#includes以更好地了解如何保持查询的紧密性。当您使用#includes时,Rails会优化查询以使查询次数最少,但仍需要您提供一些指导。
鉴于以下模型:
class Person < ActiveRecord::Base
has_many :relationships
has_many :relatives, through: :relationships, class_name: "Person", foreign_key: "relative_id"
end
class Relationship < ActiveRecord::Base
belongs_to :person
belongs_to :relative, :class_name => "Person", :foreign_key => 'relative_id'
end
当您尝试查询某人的亲属时,您希望确保包含关系和此人。
Person.where(name: 'George').includes(:relationships => :relative)
这将导致Rails进行三次查询。第一个将查询名为George的Person,第二个将是与第一个结果中的id匹配的person_id的所有Relationship,第三个将是所有ID与第二个查询中的relative_id匹配的人。
答案 1 :(得分:0)
如果在数据库规范化和适当使用预先加载时使用最佳实践构建应用程序,那么数据库的性能将无关紧要。
不要误导引入冗余数据,在多个表中使用人名以避免使用连接 - 您的数据完整性问题以及您将经历(不成功)保持数据同步的努力将是令人望而却步的,并通过更轻松的编码消除您认为可能产生的任何节省。