处理Oracle中的修订

时间:2010-11-23 16:17:50

标签: sql oracle revisions

我有一张桌子说:

CREATE TABLE "DataNode" (
   "ID" NUMBER(7,0),
   "TYPE" NUMBER(7,0),
   "NAME" VARCHAR2(100),
   "STATUS" NUMBER(7,0),
   "REVISION" NUMBER(4,0),
   "MODIFIEDAT" DATE
 );

 CREATE TABLE "DataNode_Revisions" (
   "ID" NUMBER(7,0),
   "NODEID" NUMBER(7,0),
   "TYPE" NUMBER(7,0),
   "NAME" VARCHAR2(100),
   "STATUS" NUMBER(7,0),
   "REVISION" NUMBER(4,0),
   "MODIFIEDAT" DATE
 ) COMPRESS;

所以我有这两张桌子。我从“DataNode”读取所有内容,当发生更改时,我将当前条目写入“DataNode_Revisions”,然后修改现有的“DataNode”记录。有意义吗?

这是最好的方法吗?我已经可以告诉我,当Schema改变时我会遇到问题。我没有看到更好的选择,但如果有,请告诉我!我假设将这一切保留在一个表中会导致大量的性能损失吗?我的意思是,我的记录数量会增加四倍,并且已经有很多。我认为Drupal存储了这样的节点修订,我很好奇它们如何不会遇到性能问题。

很多用户经常阅读“DataNode”。但是,很少有写入。 “DataNode_Revisions”仅在有时读取。我只是担心要保留这么多表。 “DataNode”是与此非常相似的约25个表中的一个。

4 个答案:

答案 0 :(得分:6)

将旧行存储在DataNode表中是否会产生任何性能影响取决于DataNode行的访问方式。如果读取都是当前行的单行查找,则表中的行数相对无关紧要 - 找到特定ID的当前行不会比获取行更多的工作来自当前DataNode表的那个ID(我假设ID是表的关键)。另一方面,如果您有许多查询正在对DataNode表进行表扫描,那么将行数增加四倍将增加运行这些查询所需的时间。

如果您想沿着将历史行放在DataNode表中的路径,您可能希望为当前行添加一个为空的EXPIRATION_DATE列,并为过期的行填充。然后,您可以根据EXPIRATION_DATE创建一个基于函数的索引,该索引只包含当前行的数据,即

CREATE INDEX idx_current_ids
    ON DataNode( (CASE WHEN expiration_date IS NULL THEN id ELSE null END) );

将在

等查询中使用
SELECT *
  FROM DataNode
 WHERE (CASE WHEN expiration_date IS NULL THEN id ELSE null END) = <<some id>>

显然,您可能希望创建一个具有此条件的视图,而不是每次需要当前行时重写它,即

CREATE VIEW CurrentDataNode
AS
SELECT (CASE WHEN expiration_date IS NULL THEN id ELSE null END) id,
       type,
       name,
       status
  FROM DataNode;

SELECT *
  FROM CurrentDataNode
 WHERE id = <<some value>>

答案 1 :(得分:4)

我通常使用触发器来写入'Revisions'表。是的,架构更改会强制您更新镜像表和触发/存档功能。

我认为你会遗憾地将你的所有历史以及当前的修订保留在一张表中,所以我认为你有正确的想法。

如果您想尝试为每个事务表提供一个不需要镜像表的通用解决方案,您可以考虑只使用一个修订表来将记录转换为XML并将其存储在如果你不得不经常或快速地访问它,那就不是很有用了,但是如果你真的只想存档所有东西,那就太好了。

答案 2 :(得分:2)

您有几个选择。强制您跟踪数据更改的业务需求是什么?

  • 如果您只需要在一段“短”时间内保持更改,您可以使用闪回查询从UNDO读取数据。从时间戳(bla)中选择*表;

    < / LI>
  • 如果您需要长期保留此信息,请查看名为Oracle Total Recall的功能。它与闪回查询的作用相同,但会无限期地保留更改。

  • 如果您需要更简单的东西,请不要让应用程序插入行的“旧”版本。使用填充数据的触发器。

  • 如果系统非常繁忙,您可以通过使用用作“队列”的中间表来解耦这两个表

答案 3 :(得分:2)

这将取决于应用程序。如果您使用的是11g,则可能需要查看新的闪回数据存档。我只是开始关注它以保留我们所有财务和其他关键数据的历史记录。