sql – 处理Oracle中的修订

前端之家收集整理的这篇文章主要介绍了sql – 处理Oracle中的修订前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一张桌子说:
CREATE TABLE "Datanode" (
   "ID" NUMBER(7,0),"TYPE" NUMBER(7,"NAME" VARCHAR2(100),"STATUS" NUMBER(7,"REVISION" NUMBER(4,"MODIFIEDAT" DATE
 );

 CREATE TABLE "Datanode_Revisions" (
   "ID" NUMBER(7,"NODEID" NUMBER(7,"MODIFIEDAT" DATE
 ) COMPRESS;

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

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

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

解决方法

将旧行存储在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>>

猜你在找的MsSQL相关文章