RDBMS 概念模型不太擅长维护数据的时间版本。因此,在这方面缺乏的不仅仅是甲骨文。
我不清楚您为什么认为将版本信息保持在记录级别会太慢。创建新版本太慢?还是在常规操作期间数据检索太慢?
这是你可以做到的。给定一个业务键为 CUSTOMER_REF 的表 CUSTOMERS,我通常可以这样构建它(由于空间原因,我使用缩写语法而不是最佳实践):
create table customers
( id number not null primary key
, customer_ref number not null unique key
, name varchar2(30) not null )
/
版本化的等效项如下所示:
create table customers
( id number not null primary key
, customer_ref number not null
, version_number number
, name varchar2(30) not null
, constraint whatever unique (customer_ref, version_number) )
/
这通过保持当前版本的 VERSION_NUMBER 为空,并且仅在归档时填充它来工作。任何查找都必须包含and version_number is null
. 这会有点麻烦,您可能需要将该列包含在您构建的任何其他索引中。
显然,在同一个表中维护所有版本的记录会增加表的大小,这可能会影响性能。Oracle 的分区选项在这里绝对可以提供帮助。它还将为您提供一种创建明年数据集的简洁方法。但是,它是在企业许可证之上额外收费的,因此它是一个昂贵的选择。 找到更多。.
最耗时的方面将是管理新版本表中的外键关系。假设您选择使用合成主键,归档过程将不得不生成新的 ID,然后在新版本的引用外键中将它们精心级联到它们的依赖记录。
考虑到这一点,每个版本的谨慎表格看起来都非常有吸引力。为了便于使用,我会保持当前版本不加前缀,这样存档就变成了一个简单的过程
create table customers_n as select * from customers;
您可能希望在创建版本化表时避免停机。在这种情况下,您可以使用物化视图在归档切换之前捕获表的状态。当时钟敲响十二点时,您可以关闭刷新。(警告:这是在思考,我从来没有做过这样的事情,所以在购买之前尝试一下。)
多个表(和分区)的一个相关优势是您可以将归档记录移动到只读表空间。这不仅可以保护它们免受不必要的更改,还意味着您可以将它们从后续备份中排除。
编辑
我注意到您曾评论说存档数据有时会被修改。在这种情况下,将其移动到只读表空间是不可行的。