2010-11-23 61 views
8

我有一個表,說:處理修訂中的Oracle

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」記錄。說得通?

這是最好的方法去解決它嗎?我已經可以告訴我在架構更改時會遇到問題。我沒有看到更好的選擇,但如果有一個請讓我知道!我假設將這一切全部保存在一張表中會導致巨大的性能損失。我的意思是我會超過記錄數量的四倍,而且已經有不少。我認爲Drupal存儲這樣的節點修訂,我很好奇它們如何不受它的性能問題影響。

「DataNode」不斷被許多用戶閱讀。然而,很少有人寫過這樣的話。 「DataNode_Revisions」只是偶爾讀取。我只是擔心維護這麼多桌子。 「DataNode」是與這個非常相似的〜25個表中的一個。

回答

6

在DataNode表中存儲舊行是否會影響性能取決於DataNode行的訪問方式。如果讀取是針對當前行的所有單行查找,則表中的行數是相對無關緊要的 - 它不會花費更多的工作來查找特定ID的當前行而不是獲取行從當前DataNode表中獲取該ID(我假設ID是表的關鍵)。另一方面,如果您有許多正在執行DataNode表的表掃描的查詢,那麼將行數增加四倍會增加運行這些查詢所需的時間。

如果您想要放下將歷史行放入DataNode表的路徑,那麼您可能需要爲當前行添加一個爲NULL的EXPIRATION_DATE列,併爲已過期的行填充EXPURATION_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>> 

顯然,你」 d可能希望創建一個具有此條件的視圖,而不是每當需要當前行時重寫它,即

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>> 
+0

+1:基於函數的索引思想非常好! – 2010-11-23 16:37:09

4

我通常使用觸發器來寫入'修訂'表。是的,模式更改迫使您更新鏡像表和觸發/歸檔功能。

我想你會後悔把所有的歷史和當前的修訂保存在一張表中,所以我認爲你有正確的想法。

如果你想嘗試想出一個通用的解決方案,它不需要每個事務表的鏡像表,那麼你可能會考慮只用一個修訂表來將記錄轉換爲XML並將其存儲在一個clob ...如果你必須經常或快速訪問它,那麼它並不是非常有用,但如果你真的想要將所有內容都歸檔,那麼它就非常有用。

2

你有幾個選項。什麼是業務需求,迫使你跟蹤數據的變化?

  • ,如果你只需要保持變化的時間有些「短」期間,你可以閱讀使用閃回查詢從UNDO數據.. SELECT * FROM表作爲時間戳(BLA)的;

  • 如果您需要長期保留這些信息,請查看名爲Oracle Total Recall的t功能。它與Flashback Query的功能相同,但無限期地保留這些更改。

  • 如果您需要更簡單的東西,請不要在應用程序中插入「舊」版本的行。使用填充數據的觸發器。

  • 如果系統非常繁忙,你可以通過讓你作爲一個「排隊」

2

這將依賴於應用程序中使用的中介表分離的兩個表。如果您使用11g,則可能需要查看新的閃回數據存檔。我只是開始關注它,以保留我們所有財務數據和其他重要數據的歷史記錄。