2011-09-09 29 views
3

當我從Android中的sqlite數據庫查詢中獲取遊標時,它似乎包含固定數量的行,不管數據庫發生什麼情況都不會更改。例如,如果某些行在遊標打開時被刪除,我仍然可以引用已刪除的行。這很好,但它是如何工作的?遊標如何引用刪除的行?

一個猜測可能是,sqlite知道我有一個指向該行的光標,因此保留了舊數據的副本。但是如果我有一百萬行,刪除它們並用一百萬行替換它們,看起來好像要緩存大量的數據!

UPDATE:

我現在想,這個緩存我們在Android中看到的是不是真的防彈,而不是SQLite的一部分。我創建了一個包含1,000,000行數據庫的測試,然後我查詢了數據庫打印出來的結果並將光標打開,然後我刪除了一半行,最後嘗試訪問我打開的遊標,結果是崩潰:

04-05 18:17:16.141 E/AndroidRuntime(19655): java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 
04-05 18:17:16.141 E/AndroidRuntime(19655):  at android.database.CursorWindow.nativeGetLong(Native Method) 
04-05 18:17:16.141 E/AndroidRuntime(19655):  at android.database.CursorWindow.getLong(CursorWindow.java:507) 
04-05 18:17:16.141 E/AndroidRuntime(19655):  at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75) 
04-05 18:17:16.141 E/AndroidRuntime(19655):  at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:220) 
04-05 18:17:16.141 E/AndroidRuntime(19655):  at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237) 
04-05 18:17:16.141 E/AndroidRuntime(19655):  at com.jacob.DirectDbActivity$4.run(DirectDbActivity.java:88) 

這似乎是在Android的一個bug,因爲大多數的數據庫是小的高速緩存窗口可以容納所有的結果,但在大型數據庫,這是會打你。

+0

我發現這個頁面(http://www.sqlite.org/malloc.html)說:「SQLite使用動態內存分配...來保存查詢結果。」這似乎表明結果被緩存在內存中,儘管如果你有一個非常大的結果集有明顯的限制,我猜如果緩存變得太大,必須在某個時候創建​​一個臨時文件。 – satur9nine

回答

2

最後我檢查了一個遊標是基於創建它的SQL的數據庫快照。很像數據集。如果更改數據庫,則遊標可能不知道其快照是舊的。您可以對遊標執行重新查詢,以基於創建遊標的原始SQL獲取最新數據。

+0

我認爲你是對的,但我很好奇這個地方是否有更完整的文檔。 – satur9nine

+0

從SQLiteDatabase文檔:位於第一個條目之前的Cursor對象。請注意,遊標不同步,請參閱文檔以獲取更多詳細信息。 – Pyrodante

+0

您是否有指向此文檔的鏈接?我想了解更多信息,是否有臨時文件寫入文件系統?看起來像這樣做對於包含很多行的查詢來說是一個很大的懲罰。 – satur9nine