【问题标题】:Designing a rails data schema to store snapshots of records with minimal repetition设计一个 Rails 数据模式来存储记录的快照,重复最少
【发布时间】:2018-01-29 03:08:21
【问题描述】:

我使用 Ruby on Rails 框架构建了几个 Web 应用程序,并注意到一个常见的设计问题:由于某些数据的可变性,我经常需要存储一个记录的副本,其中包含发生在一定的时间。

例如,考虑具有productsorders 表的商店应用程序。当用户放置Order 时,应用程序应在订单中存储Product 记录的副本,以便保留这些产品在订购时的状态。这样,将来对 Product 的修改不会影响过去的订单。

我通常通过引入另一个表(例如 order_products)来存储与订单关联的产品来解决此问题。每个OrderProduct 然后belongs_to 一个基Product,但仍存储Product 属性的副本;我编写了保存回调来保持两条记录的属性同步,直到用户下订单,将记录解耦。

这种设计的一个问题是productsorder_products 表之间的数据字段重复;每当我修改Product 属性时,我必须记住以同样的方式修改OrderProduct 属性更新保存回调。此外,如果Product 具有必须复制到相应OrderProduct 的关联,则表中的重复开始变得笨拙。

我如何构建一个架构来存储这些与订单相关联的产品“快照”而不重复或重复最少?

(请注意,为了清楚起见,我在此处提供了具体的 productsorders 表,但我在几个不同的场景中遇到了相同的抽象问题。)

编辑:这是一个类似的问题,作者建议使用历史表来存储快照:database structure for storing historical data。接受的答案表明了我上面提出的解决方案。

【问题讨论】:

    标签: ruby-on-rails database-design schema


    【解决方案1】:

    在这种情况下,有两种设计似乎可以最大限度地减少模式重复。两种解决方案都依赖于single table inheritance (STI)

    选项 1

    RootProductOrderProduct 通过STI 扩展Product(在products 表中添加type 列)。还将order_idroot_id 列添加到products 表中。 RootProduct 表示独立产品(与订单无关,order_id = nullroot_id = null)。相比之下,OrderProduct 与订单相关联,还与创建订单的 RootProduct 相关联。当用户将RootProduct 添加到订单时,将产品克隆为OrderProduct 并将对根产品的引用保存在root_id 中。只要订单未下,就同步两条产品记录的属性,但在用户下单后将记录解耦。 OrderProduct 记录用作产品快照。

    选项 2

    与选项 1 一样,让 RootProductFrozenProduct 通过 STI 扩展 Product(在 products 表中添加 type 列)。还将root_id 列添加到products 表中。 RootProduct 代表产品在当前时间点的状态; FrozenProduct 代表下订单时产品的过去快照。引入了order_products 表来存储与订单关联的产品。在下订单之前,订单中的每个OrderProduct 都链接到RootProduct。下单后,每个OrderProduct都会链接到一个FrozenProduct,这个FrozenProduct是通过克隆对应的RootProduct创建的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 2012-06-15
      相关资源
      最近更新 更多