2014-07-22 22 views
1

是否有可能以某種方式找出從表中刪除的行的主鍵?找出刪除並更新了哪些行

同樣,是否有可能找到表中更新的主鍵?

讓我們考慮一個簡單的例子:

我有兩個時間戳:

  • 開始
  • 結束

給我更新了所有行的主鍵/這兩個之間刪除時間戳。

表中沒有信息表明它們已被更新。

+0

主鍵的可能值是什麼?如果這些是連續的,那麼您可以編寫查詢來查找從開始到結束的缺失主鍵,並且結果輸出是被刪除的行。 –

+0

Postgres不存儲有關表活動的信息,最好的方法是自己創建一個觸發器,以便更新表上的行以進行更新,或者只是將信息寫入更新或刪除的另一個位置。 – Lucas

回答

3

不,PostgreSQL不提供類似於內置的東西。

爲此,它不得不浪費空間和I/O來跟蹤大多數人永遠不需要的東西。

如果你的主鍵是連續的和單調的,那麼你可以通過在generate_series上做一個左反連接來找到漏洞。但是,如果您使用serial(即序列)來生成密鑰,這將不起作用,因爲即使沒有插入任何內容以便刪除,任何回滾都會產生間隙。

您需要添加一個審計觸發器來記錄您要追蹤到單獨審計表的操作。你不能追溯;你不能審覈過去已有的事情。這是迄今爲止最簡單的選擇。

另一個常見的解決方案是在應用程序級別將行標記爲「已刪除」,而不實際從表中刪除它們。例如,您可以在表中設置一個deleted_atdeleted_by字段。您甚至可以使用帶有ON INSERT OR UPDATE OR DELETE DO INSTEAD觸發器的視圖使此應用程序變爲透明。

還有一個pg_audit擴展開發,使這更容易,但它還沒有準備好。


半相關側面說明:在PostgreSQL 9.5,我認爲這實際上可能是可能的最近刪除的行,VACUUM清除它們面前時,使用C擴展。 9.5將能夠記錄提交的時間戳,9.4和更低版本不會(它們只記錄事務ID)。因此,您可以通過檢查xmax並從那裏確定哪個事務ID刪除了一行,並確定它從中刪除的時間戳。你需要一個C擴展名,因爲你必須在桌上做一個「髒讀」。

+0

「如果你的主鍵是連續的和單調的,那麼你可以通過generate_series做一個左反連接」對我來說是個訣竅。 我的用例是確定在源數據庫表中刪除了哪些行,以便我可以刪除目標數據庫表中的相應記錄。 對於我的用例,2個表必須是不同的DB,並且目標DB的表中的行都具有對源DB錶行ID的反向引用。 在這個用例中,如果我每次都獲得一些額外的ID,則無關緊要,因爲替代方法是將所有剩餘的源ID帶入內存。 謝謝! :-) – aec

1

隨着Netezza有可能不只是拉主鍵,但所有被刪除的數據。

首先運行一個命令,露出刪除的記錄
set show_deleted_records=true;

然後查詢數據庫。

Select deletexid,* 
from table_name 
where deletexid>0 

這個技巧對恢復錯誤很有用。請注意,已刪除的記錄不再在reclaimgroom之後持續存在。