在android中存储大数据

时间:2014-10-26 15:52:00

标签: android sqlite

我从一个安静的服务器上拉了大量的json。我使用谷歌的GSON库来遍历这个json,它运行得很好。现在我想保存我的sqlite数据库中的所有json对象,但是我想利用事务一次添加所有这些对象。如果您没有在一个datastructe中准备好所有对象,这很难。由于我一次遍历json一个对象,我想我必须将其存储在数据结构中,例如arraylist或hashmap,然后使用数据库事务快速执行插入。但是......将大量数据(即200 000个json对象)存储到内存中的结构中会占用大量内存,并且可能会耗尽。将所有json对象放入我的sqlite数据库中的最佳方法是什么,同时不会在其他方面使用大量的存储和插入,以允许大量回收。

3 个答案:

答案 0 :(得分:1)

如果您想在一个独特的时刻添加大量数据:无论如何都会占用大量内存。 20万个大型JSON对象需要一定的内存,你不能能够改变它。

您可以保留此行为,但我认为它不是一个很好的解决方案,因为您在Android设备和服务器上都会产生巨大的内存消耗。如果您逐个接收数据并以这种方式添加它们会更好:但您需要控制服务器代码。

如果你绝对被迫保持这种行为,也许你应该同时收到所有数据,在一个巨大的JSON对象上解析它们,然后进行多次交易。检查每个事务是否已正确执行,如果没有,则将数据库恢复到良好状态。这是一个非常糟糕的方式,恕我直言......但我不知道你所有的限制。

完成:避免一次只接收大量数据。最好多个请求来获取部分数据集。它将使您的应用程序减少网络依赖:如果您松开网络2秒,可能只有一个请求将失败。因此,您只需重试一个请求并再次收到一小部分数据。只有一个巨大的请求:如果您丢失网络,则必须重试整个请求...

答案 1 :(得分:0)

我知道这不是在Android中处理大型json输入的最佳实现,但它确实很有效。

所以我的解决方案很简单:

在解析JSON代码时,使用预准备语句和db事务来执行插入。 简而言之,只要解析了JSON对象,就可以使用预准备语句和数据库事务将其插入数据库,然后转到下一个对象。

我刚刚从远程服务器通过JSON和GSON提取了210,000行,每个包含23个字段(即460万个值),同时在不到5分钟的时间内将所有这些值插入到设备上的SQLite3数据库中并且不浪费任何记忆。解析/插入的每次迭代都使用相同数量的内存,并在下一次迭代时进行清理。

所以,是的,有解决方案。显然,这不是商业应用程序或具有1000 000 +记录的表的最佳解决方案,但它对我的情况很有用。

答案 2 :(得分:0)

你有没有试过在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);
               }
       }