Database design 在PostgreSQL中实现类型2缓慢变化的维度

Database design 在PostgreSQL中实现类型2缓慢变化的维度,database-design,postgresql,Database Design,Postgresql,我计划在PostgreSQL中实现一个。 SCD的缺点是,如果像经常看到的那样使用,则不能让外键引用这些表。换句话说,我经常看到在应用程序代码中处理引用完整性。我觉得这是一种糟糕的做法,因为它可以直接在数据库中完成。添加一些触发器甚至可以对应用程序编码人员隐藏这个实现细节 我提出了以下模式。这些可以吗 一对多 多对一 多对多 嗯。我认为我们需要澄清一些关于为什么要做SCD类型2的重要误解 它应该将所有数据放在一个表中,并用日期括起来(不是修订号!) 因此,你可以: id , name

我计划在PostgreSQL中实现一个。 SCD的缺点是,如果像经常看到的那样使用,则不能让外键引用这些表。换句话说,我经常看到在应用程序代码中处理引用完整性。我觉得这是一种糟糕的做法,因为它可以直接在数据库中完成。添加一些触发器甚至可以对应用程序编码人员隐藏这个实现细节

我提出了以下模式。这些可以吗

一对多 多对一 多对多
嗯。我认为我们需要澄清一些关于为什么要做SCD类型2的重要误解

它应该将所有数据放在一个表中,并用日期括起来(不是修订号!)

因此,你可以:

   id   ,  name    ,  valid_from, valid_to
  1111  , MyBook   , '2009-03-01', '9999-12-31'

After an update:
  1111  , Mybook   , '2009-03-01', '2009-06-20'
  1111  , Mybook   , '2009-06-21', '9999-12-31'
“pages”数据库中应存在具有有效起始日期和有效截止日期的类似结构

关键是,现在您可以通过以下方式获得最新版本:

select * from books where valid_to = '9999-12-31'
或者获取4月1日有效的版本

select * from books where valid_to >= '2009-04-01' and valid_from <= '2009-04-01'

select*from books where valid\u to>='2009-04-01'和valid\u from我知道现在回答这个问题有点晚了,但我认为这对寻找与你一样东西的人可能有用

我们已经编写了一个模块来实现与Django一起使用的SCDType2。它是用PostgreSQL测试的,所以它应该符合您的要求。 它还涵盖了一对一和许多关系


有关更多详细信息,请在GitHub上查找CleanServerVersion或直接转到。

不完全如此。我同意这个解决方案并不完美,因为没有简单的方法来确定最新版本。但这是一个简单的例子。细节和细节是很难解决的。我的问题的重点。SCD类型2的定义是使用“生效日期”和“截止日期”列来构建实体的完整历史记录。您的方案可以工作,但它不是SCD2。SCD2定义没有说明所需的“有效性”列。它只声明“每次更改都会插入一个新行”。当然,您需要一个鉴别器来确定“当前”值。但如何做到这一点并不是一成不变的。事实上,使用“version”列可能与使用有效的from/-to列一样常见。实现方式有所不同,但最终仍是“2型”。-作为参考,我可以引用维基百科关于SCDs的文章和David Marco的“构建和管理元数据存储库”,ISBN 0-471-35523-2-我手边没有我的DB书,所以我不能引用它。我刚刚与我们的一位数据库专家讨论了这一点。他说得很对。为有效from/-to列的使用提供了一个非常坚实的“存在理由”。有了这些列,您可以查询特定的时间点(例如:“1999年12月31日我的数据是什么样子的”)。如果仅使用修订号,则无法执行此操作。因此,剩下的唯一一件事就是决定:“我需要这样的查询吗?”。或者:“我想从我的数据中提取什么信息?”看起来这个github回购已存档。所以它不再被维护和使用了?嗨@TejusPrasad,事实上,它不再被维护了。自由地去叉和适应。
   id   ,  name    ,  valid_from, valid_to
  1111  , MyBook   , '2009-03-01', '9999-12-31'

After an update:
  1111  , Mybook   , '2009-03-01', '2009-06-20'
  1111  , Mybook   , '2009-06-21', '9999-12-31'
select * from books where valid_to = '9999-12-31'
select * from books where valid_to >= '2009-04-01' and valid_from <= '2009-04-01'