2010-05-25 77 views
5

我正在使用SQLite數據庫來存儲來自數據記錄器的值。數據記錄器最終將填滿計算機上所有可用的硬盤空間。我正在尋找一種方法,一旦達到某個限制,就會從數據庫中刪除最後25%的日誌。SQLite刪除數據庫中最後25%的記錄

使用下面的代碼:

$ret = Query('SELECT id as last FROM data ORDER BY id desc LIMIT 1 ;'); 
$last_id = $ret[0]['last'] ; 
$ret = Query('SELECT count(*) as total FROM data'); 
$start_id = $last_id - $ret[0]['total'] * 0.75 ; 
Query('DELETE FROM data WHERE id < '. round($start_id, 0)); 

一個日誌文件被旁邊,直到腳本失敗,填補了硬盤上的剩餘空間數據庫中創建。

如何/我可以停止創建此日誌文件? 無論如何將所有三個SQL查詢合併到一個語句中?

回答

2

如果日誌是問題的唯一原因,那麼可以嘗試讓SQLite在內存中執行日誌記錄,或者關閉它。

the docs

PRAGMA journal_mode;
PRAGMA database.journal_mode;
PRAGMA journal_mode = DELETE | TRUNCATE | PERSIST | MEMORY | OFF
PRAGMA database.journal_mode = DELETE | TRUNCATE | PERSIST | MEMORY | OFF

此編譯指示查詢或設置與當前數據庫連接關聯的數據庫的日誌模式。

該編譯指示的前兩種形式查詢當前日誌模式。在第一種形式中,返回默認的journal_mode。默認日誌記錄模式是由後續ATTACH語句添加到連接的數據庫使用的模式。第二種形式返回特定數據庫的當前日記模式。

最後兩種形式更改日記模式。第四種形式更改特定數據庫連接的日誌記錄模式。對主數據庫(由原始的sqlite3_open(),sqlite3_open16()或sqlite3_open_v2()接口調用打開的數據庫)使用「main」,並將「temp」用於包含TEMP表的數據庫。第三種形式更改所有數據庫的日誌模式,並更改將用於後續ATTACH命令添加的新數據庫的默認日誌記錄模式。新的日記模式返回。如果日記模式無法更改,則返回原始日記模式。

DELETE日誌記錄模式是正常行爲。在DELETE模式下,回滾日誌在每個事務結束時被刪除。事實上,刪除操作是導致事務提交的操作。 (請參閱標題爲「Atomic Commit In SQLite」的文檔以獲取更多詳細信息。)

TRUNCATE日記記錄模式通過將回滾日誌截斷爲零而不是刪除它來提交事務。在很多系統上,截斷文件比刪除文件要快得多,因爲包含的目錄不需要改變。

PERSIST日記模式可防止在每次事務結束時刪除回滾日誌。相反,日誌的標題被零覆蓋。這將阻止其他數據庫連接將日記回滾。PERSIST日誌模式在平臺上的優化很有用,刪除或截斷文件比用零覆蓋文件的第一個塊要昂貴得多。

MEMORY日誌記錄模式將回滾日誌存儲在易失性RAM中。這節省了磁盤I/O,但是犧牲了數據庫的安全性和完整性。如果在設置MEMORY日誌記錄模式時使用SQLite的應用程序在事務中間崩潰,那麼數據庫文件很可能會損壞。

OFF日誌模式完全禁用回滾日誌。沒有創建回滾日誌,因此永遠不會有回滾日誌來刪除。 OFF日誌模式禁用SQLite的原子提交和回滾功能。 ROLLBACK命令不再起作用;它的行爲不確定。日誌模式爲OFF時,應用程序必須避免使用ROLLBACK命令。如果應用程序在OFF日誌模式設置時在事務中間崩潰,那麼數據庫文件很可能會損壞。

請注意,內存數據庫的journal_mode是MEMORY或OFF,不能更改爲不同的值。嘗試將內存數據庫的journal_mode更改爲除MEMORY或OFF之外的任何設置都將被忽略。還要注意,事務處於活動狀態時,journal_mode無法更改。