处理Oracle中的修订

jre*_*d42 8 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;
Run Code Online (Sandbox Code Playgroud)

所以我有这两张桌子.我从"DataNode"读取所有内容,当发生更改时,我将当前条目写入"DataNode_Revisions",然后修改现有的"DataNode"记录.说得通?

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

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

Jus*_*ave 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) );
Run Code Online (Sandbox Code Playgroud)

将在查询中使用

SELECT *
  FROM DataNode
 WHERE (CASE WHEN expiration_date IS NULL THEN id ELSE null END) = <<some id>>
Run Code Online (Sandbox Code Playgroud)

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

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>>
Run Code Online (Sandbox Code Playgroud)


aw *_*rud 5

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

我认为您会后悔将所有历史记录以及当前修订版本保存在一个表中,所以我认为您的想法是正确的。

如果您想尝试提出一个不需要为每个事务表都提供镜像表的通用解决方案,您可能会考虑只使用一个修订表,您可以在其中将记录转换为 XML 并将其存储在 clob 中。 . 如果您必须经常或快速访问它,则不是很有用,但如果您真的只想存档所有内容,则很好。