提问人:Jens Schmidt 提问时间:11/30/2019 更新时间:12/1/2019 访问量:45
数据库建模最佳实践:处理与同一“基础”的关联
Database modeling best practice: Dealing with Associations to the same "base"
问:
我尝试规范化我的数据库模型。但在这种情况下,我不知道该怎么做。给出以下模型:
- 客户拥有多个系统(has_many:systems)
- 群集具有许多系统(has_and_belongs_to_many:systems)
我想显示客户的所有系统。那将是:.这已经奏效了。@customer.systemobjects.each
然后,我可以将系统添加到集群中(我提到的是“HABTM”关联)。在我的客户视图中,我只想显示与集群无关的系统(也使用 )。Cluster.includes(:systems).where(systems: { id: sysid }).present?
现在我的问题是:我也想显示特定客户的所有集群(以及该集群的系统)。但是,现在,我只能通过系统与客户建立联系。对我来说,在集群对象中添加对客户的引用会更容易(即使我已经在系统中拥有此信息)。
我应该添加此引用吗?无论如何,它与规范化有关吗?从最佳实践的角度来看,对于一般的数据库和具体的 Ruby On Rails,您如何评估这种情况?当我只通过系统(我如何在 rails 中做到这一点)时,如何通过客户的每个集群来检查它的最佳方式?
答:
我想你更喜欢这样的东西:
class Customer
has_many :systems
has_many :clusters, through :systems # expect `clusters_id` in System, which is typical
# ...other code
end
class System
belongs_to :customer
belongs_to :cluster
# ...other code
end
class Cluster
has_many :systems
has_many :customers, through :systems # expect `customer_id` in System, which is typical
# ...other code
end
正如您的模型已经暗示的那样,这会产生三个表,但使用系统表作为其他两个表的“铰链”查找表,而不暗示集群属于系统(据我所知,这没有意义 IRL)。
我经常发现,除非你们真的有相互归属感,否则它通常比 HABTM 更容易、更好的选择。您可以转到 Rails Guides here 和 here (指南: “Active Record Associations”) 以获取有关使用的更多信息。对于您遇到的问题,绝对值得了解该指南(尽管公平地说,可能需要一些经验才能充分了解各种选项以及它们的帮助)。has_many :through
:through
现在,当您想要引用客户在其中拥有系统的集群时,您只需要编写如下内容:
my_customer = Customer.find(some_id)
customer_clusters = customer.clusters
customer_systems = customer.systems
若要查找群集(以及群集系统)的所有客户,请编写如下内容:through
target_cluster = Cluster.find(some_id)
cluster_customers = target_cluster.customers
如果你想要生成这些层次结构(例如,在它们所属的集群下分组的客户系统),它是这样的:
my_customer = Customer.find(some_id)
customers_systems = customer.systems.includes(:cluster) # this brings in the associated cluster records without additional database operations
然后,根据您打算如何显示或返回数据,迭代或使用生成的数据。group_by
customer_systems
评论
systems
t.reference
cluster_id
belongs_to
评论
through
cluster_id