0

当谈到具有“历史”
价值的关系时,我在各种选择之间犹豫不决。

例如,假设用户在某个日期购买了一件商品......如果我只是以经典方式存储它,例如:

transation_id: 1
user_id: 2
item_id: 3
created_at: 01/02/2010

然后很明显,用户可能会更改其名称,该项目可能会更改其价格,并且 3 年后,当我尝试创建发生的事情的报告时,我有虚假数据。

我有两个选择:

  1. 像我之前展示的那样保持愚蠢,但使用类似https://github.com/airblade/paper_trail的东西并执行以下操作:

    t = Transaction.find(1);
    u = t.user.version_at(t.created_at)
    
  2. 创建一个类似transaction_usersand的数据库,transaction_items并在进行事务时将用户/项目复制到这些表中。然后结构将变为:

    transation_id: 1
    transaction_user_id: 2
    transaction_item_id: 3
    created_at: 01/02/2010
    

两种方法都有其优点,但解决方案 1 看起来要简单得多……您是否发现解决方案 1 有问题?这个“历史数据”问题通常是如何解决的?我必须为我的项目解决这样的 2-3 个模型的问题,您认为最好的解决方案是什么?

4

2 回答 2

0

我会选择 PaperTrail,它保留了我所有模型的历史,甚至它们的破坏。如果它不能扩展,我以后总是可以切换到第 2 点。

于 2014-03-25T14:08:45.727 回答
0

以商品价格为例,您还可以:

  1. 在交易表中存储一份当时的价格
  2. 为商品价格创建临时表

在交易表中存储价格的副本:

TABLE Transaction(
 user_id      -- User buying the item
,trans_date   -- Date of transaction
,item_no      -- The item
,item_price   -- A copy of Price from the Item table as-of trans_date
)

获取交易时的价格很简单:

select item_price
  from transaction;

为商品价格创建时态表:

TABLE item (
   item_no
  ,etcetera -- All other information about the item, such as name, color
  ,PRIMARY KEY(item_no)
)

TABLE item_price(
   item_no
  ,from_date
  ,price
  ,PRIMARY KEY(item_no, from_date)
  ,FOREIGN KEY(item_no)
      REFERENCES item(item_no)
)

第二个表中的数据如下所示:

ITEM_NO  FROM_DATE   PRICE
=======  ==========  =====
   A     2010-01-01  100
   A     2011-01-01  90
   A     2012-01-01  50
   B     2013-03-01  60

说从 2010 年 1 月 1 日开始,文章 A 的价格是 100。它将 2011 年 1 月的第一个更改为 90,然后从 2012 年 1 月 1 日再次更改为 50。

您很可能会将 TO_DATE 添加到表中,即使它是非规范化(TO_DATE 是下一个 FROM_DATE)。

查找交易时的价格将类似于以下内容:

select t.item_no
      ,t.trans_date
      ,p.item_price
  from transaction t
  join item_price  p on(
       t.item_no = p.item_no
   and t.trans_date between p.from_date and p.to_date
  );


ITEM_NO TRANS_DATE PRICE
======= ========== =====
   A    2010-12-31  100
   A    2011-01-01   90
   A    2011-05-01   90
   A    2012-01-01   50
   A    2012-05-01   50
于 2014-03-04T12:32:03.780 回答