我从一个宁静的服务器上拖出大量的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