在我的公司,我们正在尝试缓存一些我们从API查询的数据。我们正在使用Rails。我的两个模型是'查询'和'响应'。我想在Query和Response之间创建一对多关系,其中一个查询可以有很多响应。
我认为这是正确的做法。
Query = [query]
Response = [query_id, response_detail_1, response_detail_2]
然后,在模型中,我做了以下数据关联:
class Query < ActiveRecord::Base
has_many :response
end
class Response < ActiveRecord::Base
belongs_to :query
end
所以,规范地说,每当我想找到给定查询的所有响应时,我都会这样做 -
"_id" = Query.where(:query => "given query").id
Response.where(:query_id => "_id")
但是我的老板让我在Query模型中使用了一个Array列,删除了模型之间的数据关联,并将每个响应记录的id放在Query模型的该数组列中。所以,现在查询模型看起来像
Query = [query_id, [response_id_1, response_id_2, response_id_3,...]]
我只是想知道这两种方式的优点和缺点是什么,哪种方法是正确的。
答案 0 :(得分:0)
如果关系实际上是一对多的关系,那么“标准”方法就是您最初建议的方法,或使用联结表。通过使用数组,您可以通过FK获得参照完整性。 Postgres几乎对数组列有FK约束,但从我研究的内容看起来它似乎不在路线图中: http://blog.2ndquadrant.com/postgresql-9-3-development-array-element-foreign-keys/
如果将其视为非规范化/缓存辅助,则可能会从阵列方法中获得一些性能优势。有关这方面的一些信息,请参阅此答案,但仍建议使用联结表: https://stackoverflow.com/a/17012344/4280232。这个答案和评论还提供了关于阵列性能与连接性能的一些想法: https://stackoverflow.com/a/13840557/4280232
使用数组的另一个好处是数组会保留顺序,所以如果顺序很重要,那么你可以获得一些好处: https://stackoverflow.com/a/2489805/4280232
但即使这样,您也可以将订单直接放在响应表上(假设它们对每个查询都是唯一的),或者您可以将它放在连接表上。
因此,总而言之,您可能会从数组外键中获得一些性能优势,并且它们可能有助于排序,但您将无法对它们强制执行FK约束(截至撰写本文时) 。除非这里出现特殊情况,否则最好坚持使用“子表上的FK列”方法,因为这种情况更为常见。
当然,这一切都主要适用于SQL数据库,我注意到你现在没有在你的问题中指明。如果您正在使用NoSQL,可能还有其他约定。