2011-04-11 44 views
8

是否可以有效地對數據庫表進行尾部追蹤,以便在添加新行時立即向新行通知應用程序?任何數據庫都可以使用。'tail -f'數據庫表

回答

7

使用ON INSERT觸發器。

您將需要檢查有關如何使用插入記錄中包含的值調用外部應用程序的細節,或者將您的'應用程序'作爲SQL過程編寫並讓它在數據庫中運行。

聽起來好像你會想要在數據庫上進行一般性的修改,然後再用命令行方法將自己繪製到角落。

5
  • 是的,如果數據庫是一個扁平的文本文件,並在最後完成追加。
  • 是的,如果數據庫以某種其他方式支持此功能;檢查相關手冊。
  • 否則,沒有。數據庫往往是二進制文件。
+0

你知道一個支持這個特性的特定數據庫嗎?我不知道。 – avid 2011-04-11 17:11:47

+0

@avid:不,對不起。 – 2011-04-11 17:15:17

1

我不知道,但這可能適用於原始/平面文件數據庫,但據我瞭解(我可能是錯的)現代數據庫文件被加密。因此讀取新添加的行將不適用於該命令。

1

我想大多數數據庫都允許寫入觸發器,並且您可以在寫入時觸發一個腳本,告訴您發生了什麼。我不知道有什麼信息可用,因爲它取決於個人數據庫。

0

在Linux上,tail似乎使用inotify來告訴文件何時更改 - 它可能會在其他操作系統上使用類似的文件系統通知框架。因此它會檢測文件修改。

也就是說,tail在每次檢測到更改後執行fstat()調用,除非文件大小增加,否則不會輸出任何內容。現代數據庫系統使用隨機文件訪問並重新使用數據庫頁面,因此很可能插入的行不會導致備份文件大小發生變化。

如果使用DB觸發器或任何機構的數據庫管理系統提供了監視數據庫更新,因爲不是所有的文件更新一定行插入你最好不要直接使用inotify(或類似),甚至更好。

0

我只是在發佈的glowcoder完全相同的響應的中間,再加上另一個想法:

的低技術含量的方式來做到這一點是有一個時間戳字段,並且有一個程序運行一個查詢每n分鐘查找時間戳大於最後一次運行的記錄。如果您使用序列,或者添加布爾字段「已處理」,則可以通過存儲最後看到的關鍵字來實現相同的概念。

0

使用oracle,您可以選擇一個名爲'rowid'的psuedo-column,它爲表中的行提供唯一標識符,而rowid則是序數...新行獲得的分配rowid大於任何現有的rowid。

因此,首先從table_name的

選擇MAX(ROWID)我認爲原因之一爲提出的問題是,有表中的許多,許多行...所以這第一步將會對數據庫徵稅一些並花費一些時間。

然後,SELECT * FROM表名,其中ROWID>「whatever_that_rowid_string_was」

你還是要定期運行的查詢,但它現在僅僅是一個快速和廉價的查詢

+0

只是重新閱讀這個問題...特別是'任何數據庫部分'...回答撤回:)我suk – Rondo 2011-04-15 05:05:37

1

有幾個選擇這裏,其中一些已經注意到:

  • 定期輪詢新行。儘管MVCC的工作方式可行,但如果上次查詢時在交易中期有兩個INSERTS,則可能會錯過一行。
  • 定義一個觸發器函數,它可以爲每個插入件做一些工作。 (在Postgres中,您可以調用NOTIFY命令,其他進程可以偵聽到。)您可以將觸發器和寫入操作組合到unpublished_row_ids表中,以確保您的拖尾過程不會錯過任何內容。 (拖尾過程會在處理它們時從unpublished_row_ids表中刪除ID。)
  • 掛鉤數據庫的複製功能,如果它提供任何。這應該有保證行不會錯過的方法。

我已經寫了更多關於如何用Postgres在http://btubbs.com/streaming-updates-from-postgres.html做所有這些選項的更多細節。