Rails 数据库设置多态性
Rails database setup Polymorphism
我们必须创建一个请求系统,其中包含大约 10 种不同类型的请求。所有这些请求都属于我们应用程序的 'accounting' 方面。因此我们称它们为 "Accounting requests"。
所有请求可能只共享几列,每个请求最多有 20 列。
我们开始怀疑,当我们开始不得不进行非常复杂的连接或查询时,例如,将所有请求类型提取到单个 table 然后对其进行排序。
也许只使用单一 Table 继承会更容易,因为它将有一个类型列,我们将使用一个 table 来存储所有 10 种会计请求类型。
您如何看待将 STI 用于如此多的多态关联和需求?
基本上,它会有这样的模型:
AccountingRequest
BillingRequest < AccountingRequest
CheckRequest < AccountingRequest
CancellationRequest < AccountingRequest
每个子类大约有 10 多个字段。
目前正在阅读有关多重 Table 继承 here 的内容。在这种情况下,这似乎是符合我要求的解决方案。虽然还不确定。
听起来可行。
当我对此进行调查时,我发现广泛使用值对象有助于控制某些属性对某些类型的不适用性。
在我的例子中,我有多种类型的产品,例如,其中一些没有特定的尺寸。在那些情况下,我在适当的地方使用空对象来指示 "Not applicable"。
编辑:我还发现 composed_of 语法非常方便:https://apidock.com/rails/ActiveRecord/Aggregations/ClassMethods/composed_of
您可以在那种情况下使用 STI。但是制作 STI 需要将所有列合并为一个 table,这不是一个好主意。 table 的字段数会很大。
我认为你应该像下面这样分成两个 tables...
请求:请求table将是保存请求类型信息的多态table。
RequestItem:请求项table会将所有20个字段记录保存到table中,并且会有一个请求的外键table。请求项 table 将在数据库中有两个字段,称为键和值。
目前我在这种情况下使用了一些 NoSQL。 Postgresql's JSONB
类型允许存储多级 ruby 哈希。它还提供了丰富的功能:数据库级约束、索引和查询运算符。
因此,通用属性以标准方式存储,并且 child 特定 - 在 jsonb
中。然后您可以在此基础上使用您需要的任何东西:STI、值 Objects 模式、序列化或只是为每个 child 创建范围。我更喜欢最后一个——我的模型很薄,大多数约束都是数据库级别的,所有业务逻辑都在服务中 类。
优点:
- 在需要添加一个 child 类型时避免
alter table
在大表上
- 保持我的查询高效
- 防止存储和选择不必要的列
- JSON API 的开箱即用序列化
缺点:
- 有点无模式
- 供应商锁定
如果您的模型都具有相同的属性,则 STI 非常适合。
但是,如果您的子 类 开始具有特定于它们的属性而不适用于其他属性,则 STI 可能会导致大量空列。在那种情况下,我通常更喜欢使用多态关联。
这一 railscast 集很好地说明了 2
之间的区别
我们必须创建一个请求系统,其中包含大约 10 种不同类型的请求。所有这些请求都属于我们应用程序的 'accounting' 方面。因此我们称它们为 "Accounting requests"。
所有请求可能只共享几列,每个请求最多有 20 列。
我们开始怀疑,当我们开始不得不进行非常复杂的连接或查询时,例如,将所有请求类型提取到单个 table 然后对其进行排序。
也许只使用单一 Table 继承会更容易,因为它将有一个类型列,我们将使用一个 table 来存储所有 10 种会计请求类型。
您如何看待将 STI 用于如此多的多态关联和需求?
基本上,它会有这样的模型:
AccountingRequest
BillingRequest < AccountingRequest
CheckRequest < AccountingRequest
CancellationRequest < AccountingRequest
每个子类大约有 10 多个字段。
目前正在阅读有关多重 Table 继承 here 的内容。在这种情况下,这似乎是符合我要求的解决方案。虽然还不确定。
听起来可行。
当我对此进行调查时,我发现广泛使用值对象有助于控制某些属性对某些类型的不适用性。
在我的例子中,我有多种类型的产品,例如,其中一些没有特定的尺寸。在那些情况下,我在适当的地方使用空对象来指示 "Not applicable"。
编辑:我还发现 composed_of 语法非常方便:https://apidock.com/rails/ActiveRecord/Aggregations/ClassMethods/composed_of
您可以在那种情况下使用 STI。但是制作 STI 需要将所有列合并为一个 table,这不是一个好主意。 table 的字段数会很大。
我认为你应该像下面这样分成两个 tables...
请求:请求table将是保存请求类型信息的多态table。
RequestItem:请求项table会将所有20个字段记录保存到table中,并且会有一个请求的外键table。请求项 table 将在数据库中有两个字段,称为键和值。
目前我在这种情况下使用了一些 NoSQL。 Postgresql's JSONB
类型允许存储多级 ruby 哈希。它还提供了丰富的功能:数据库级约束、索引和查询运算符。
因此,通用属性以标准方式存储,并且 child 特定 - 在 jsonb
中。然后您可以在此基础上使用您需要的任何东西:STI、值 Objects 模式、序列化或只是为每个 child 创建范围。我更喜欢最后一个——我的模型很薄,大多数约束都是数据库级别的,所有业务逻辑都在服务中 类。
优点:
- 在需要添加一个 child 类型时避免
alter table
在大表上 - 保持我的查询高效
- 防止存储和选择不必要的列
- JSON API 的开箱即用序列化
缺点:
- 有点无模式
- 供应商锁定
如果您的模型都具有相同的属性,则 STI 非常适合。
但是,如果您的子 类 开始具有特定于它们的属性而不适用于其他属性,则 STI 可能会导致大量空列。在那种情况下,我通常更喜欢使用多态关联。
这一 railscast 集很好地说明了 2
之间的区别