不确定主题是否完全传达了我想要实现的目标,但让我解释一下:
我们正在构建一个使用Oracle作为存储后端的应用程序。每年,去年的数据集将“存档”,并从头开始创建和填充新实例。 在同一模式中有哪些选项可以做?
是否有可用的分区/个性/命名空间可以让我们在Oracle中实现这一目标?
我的oracle经验相当有限,任何帮助将不胜感激!
答案 0 :(得分:1)
RDBMS概念模型在维护数据的时态版本方面不是很好。因此,不仅仅是Oracle在这方面缺乏。
我不清楚为什么你认为保持记录级别的版本信息会太慢。创建新版本太慢了?或者在常规操作期间进行数据检索的速度太慢?
这是你如何做到的。给定一个具有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保持为null来实现,并且只在归档时填充它。任何查找都必须包含and version_number is null
。这将有点麻烦,您可能需要在您构建的任何其他索引中包含该列。
显然,在同一个表中维护所有版本的记录会增加表的大小,这可能会影响性能。 Oracle的分区选项在这里肯定有帮助。它还可以为您提供创建明年数据集的简洁方法。但是,它是企业许可证之上的额外费用,因此它是一种昂贵的选择。 Find out more.。
最耗时的方面是在新版本的表中管理外键关系。假设您选择使用合成主键,归档过程将必须生成新ID,然后在引用外键的新版本中将它们精心地级联到其依赖记录。
考虑到这一点,每个版本的谨慎表格看起来非常有吸引力。为了便于使用,我会保持当前版本不带前缀,以便归档成为一个简单的过程
create table customers_n as select * from customers;
您可能希望在创建版本化表时避免停机。在这种情况下,您可以使用物化视图在归档切换的准备期间捕获表的状态。当时钟达到12时,您可以关闭刷新。 (警告:这是在思考,我从来没有做过这样的事情,所以在购买之前先试试。)
多个表(和分区)的一个相关优点是您可以将存档记录移动到READ ONLY表空间。这不仅可以保护它们免受不必要的更改,还意味着您可以将它们从后续备份中排除。
修改强>
我注意到您已经评论过,可以偶尔修改存档数据。在Taht的情况下,将它移动到READ ONLY表空间不是一个常规。
答案 1 :(得分:0)
我唯一能说的就是APC所说的是关于你要求“命名空间”。
Oracle中的命名空间是一种架构,您可以在每个架构中拥有相同的对象名称。
当然这一切都取决于你的应用程序必须如何访问多个版本,但在我使用某种命名约定来维护同一模式中的表版本之前,我会倾向于每年使用不同的模式。原因是,最终你会做恶梦。至少对于不同的模式,所有DDL都可以是相同的,对对象的所有引用都是相同的,并且ER模型和查询工具之类的工具将在该模式的上下文中工作。数据模型会发生变化,因此在某些时候您可能需要运行一些比较工具,并且如果您的所有表都使用某种版本的后缀命名为funky,那么这将无效。
使用fromuser / touser或remap_schema选项可以使用导出或数据泵快速复制/移动模式,因此除了对新版本中的去年数据进行任何清理之外,您不需要太多代码。
我发现模式作为“容器”非常有用,而且我主持的大多数应用程序只具有模式级权限,所以我保证应用程序可以轻松快速地从一个实例移动到实例,或者应用程序的多个副本可以是在同一个实例上并排托管。
答案 2 :(得分:0)
可能会在多年之间改变架构。例如,在2010年,您有15列,但在2011年,您添加了第16列。 如果是这样,相同的应用程序将同时适用于2010年和2011年的数据。
如果架构是静态的,我会选择带有'YEAR'列的表格并使用VPD/RLS/FGAC来应用YEAR ='2010'谓词。
如果性能有问题,我只会担心分区。
答案 3 :(得分:-1)
1)按行分隔年份和行中的某个日期字段。
2)在每个表的末尾添加它,并使用序列和触发器填充它。
3)然后在此col。上按间隔年份进行分区。