我從一個寧靜的服務器上拖出大量的json。我使用谷歌的GSON庫來遍歷這個json,它效果很好。現在我想將所有json對象保存在我的sqlite數據庫中,但是我想使用事務來一次添加所有這些對象。如果你沒有在一個datastructe中準備好所有的對象,這很困難。由於我一次遍歷一個json對象,所以我想我必須將其存儲在數據結構中,例如arraylist或hashmap,然後使用數據庫事務來快速執行插入操作。然而......將大量數據(又稱爲20000個json對象)存儲到內存中的結構中可能佔用大量內存,並且可能會用完。將所有json對象放入我的sqlite數據庫中的最佳方式是什麼?同時,不要使用其他語言中的許多menory來存儲和插入,以便進行大量的回收。在android中存儲大量數據
回答
我知道這不是在Android中處理大型json輸入的最佳實現,但它確實很好。
所以我的解決方案很簡單:
在解析JSON代碼,利用預處理語句和數據庫事務執行插入。 因此,簡而言之,只要解析JSON對象,就可以使用準備好的語句和db事務將該信息插入到數據庫中,然後轉到下一個對象。
我剛剛從遠程服務器通過JSON和GSON抽取了210,000行,每個23個字段(即460萬個值),同時將所有這些值插入到設備上的SQLite3數據庫中,少於5個分鐘而不浪費任何內存。每次解析/插入迭代使用相同數量的內存,並在下一次迭代時進行清理。
所以是的,有解決方案。顯然,這不是商業應用程序或具有1000 000條記錄的表格的最佳解決方案,但對我的情況非常有用。
如果你想在一個獨特的時刻添加大量的數據:無論如何它會佔用大量的內存。 200 000個大的JSON對象需要一定的內存,並且您將而不是能夠更改它。
您可以保持這種行爲,但我認爲這不是一個很好的解決方案,因爲您在Android設備和服務器上都創建了巨大的內存消耗。如果您逐個接收數據並以這種方式添加數據會更好:但您需要控制服務器代碼。
如果你是絕對被迫保持這種行爲,也許你應該在同一時間接收所有的數據,解析它們在一個巨大的JSON對象,然後進行多個事務。檢查每個事務是否正確執行,如果沒有,則將數據庫恢復到良好狀態。這是一個非常糟糕的方式,恕我直言...但我不知道你所有的限制。
完成:避免一次只接收大量數據。多次請求獲取部分數據集會更好。它會使您的應用程序減少網絡依賴性:如果您將網絡斷開2秒,則可能只有一個請求會失敗。所以你將不得不重試只有一個請求,並再次收到一小部分數據。只有一個巨大的請求:如果你鬆動了網絡,你將不得不重試整個請求...
Thx的意見。我同意這樣做並不理想,但我對項目的某些方面幾乎沒有控制權。將考慮多個數據塊而不是一個大的請求。然而,使用gson做它並不會創建任何大內存事務,因爲一次執行一個數據庫插入也沒有問題,因爲它可以回收內存,但需要很長時間。我想看看我是否可以在交易時保持數據庫的開放。 – Janpan 2014-10-26 17:19:39
你有沒有試過在Android內部數據庫(SQLite)中添加大量數據(我的意思是很多,在我的情況下是2600行數據)?
如果是這樣,你可以和我一樣走上同樣的道路。
我試過一個正常的InsertStatement,這是減慢速度的方法(在我的模擬器中10秒)。然後我嘗試了PreparedStatements。時間比較好,但仍然不能接受。 (6秒)。經過一段令人沮喪的編寫代碼的時間,然後扔掉它,我終於找到了一個很好的解決方案。
Android-OS提供InsertHelper作爲快速插入方式。
爲了讓你的性能的概述(用垃圾電腦模擬器上進行測量,試圖插入2600行數據):
Insert-Statement
10 seconds
Prepared-Statements
6 seconds
InsertHelper
320 ms
你甚至可以多用暫時禁用線程加快插入鎖。這將增加約30%的性能。然而,重要的是要確保每次只有一個線程正在使用數據庫,而不是因爲線程安全而插入數據。
public void fillDatabase(HashMap<String, int[]> localData){
//The InsertHelper needs to have the db instance + the name of the table where you want to add the data
InsertHelper ih = new InsertHelper(this.db, TABLE_NAME);
Iterator<Entry<String, int[]>> it = localData.entrySet().iterator();
final int firstExampleColumn = ih.getColumnIndex("firstExampleColumn");
final int secondExampleColumn = ih.getColumnIndex("secondExampleColumn");
final int thirdExampleColumn = ih.getColumnIndex("thirdExampleColumn");
try{
this.db.setLockingEnabled(false);
while(it.hasNext()){
Entry<String, int[]> entry = it.next();
int[] values = entry.getValue();
ih.prepareForInsert();
ih.bind(firstExampleColumn, entry.getKey());
ih.bind(secondExampleColumn, values[0]);
ih.bind(thirdExampleColumn, values[1]);
ih.execute();
}
}catch(Exception e){e.printStackTrace();}
finally{
if(ih!=null)
ih.close();
this.db.setLockingEnabled(true);
}
}
- 1. 在MySQL中存儲大量數據?
- 2. 在localStorage中存儲大量數據
- 3. 在ASP.NET中存儲大量數據
- 4. 將大量數據存儲在SQLite中
- 5. 存儲大量數據點?
- 6. 存儲大量數據
- 7. 在android中緩存大量數據
- 8. 在Android中存儲大量的後端數據
- 9. 如何在android中存儲大量的數據庫文件?
- 10. 如何在Android中私密存儲大數據量?
- 11. WP7數據存儲 - 大量數據
- 12. 在android中存儲大量圖像
- 13. 在本地存儲大量數據
- 14. 存儲大量圖像android
- 15. Android存儲大量圖像
- 16. 將大量圖形數據結構存儲在數據庫中
- 17. 在MySQL數據庫中存儲大量數據的問題
- 18. 將大量數據存儲在數據庫中
- 19. 爲Android應用本地或在線存儲大量數據?
- 20. 在android數據庫中存儲數據
- 21. 在ASP.net會話變量中存儲的最大數據量
- 22. 如何在內存中存儲大量的文本數據?
- 23. 將大量的數據存儲在內存中
- 24. java>存儲大量數據
- 25. 數據類型存儲大量
- 26. Java:數據結構存儲大量字
- 27. 存儲和訪問大量數據的
- 28. 存儲和查詢大量數據
- 29. C#:存儲大量數據的my.settings
- 30. QHash存儲大量的數據
如果它是最好的,你應該接受你自己的答案。這樣,未來的讀者將很容易找到解決方案。 – mithrop 2014-10-27 08:59:24
我會在20小時內。 @mithrop – Janpan 2014-10-27 19:35:43