【问题标题】:Android how to query huge database in android (cursor size is limited to 1MB)Android如何在android中查询庞大的数据库(光标大小限制为1MB)
【发布时间】:2012-04-10 01:25:40
【问题描述】:

我正在开发一个有时需要查询的应用程序,一个有超过 4k 行的数据库,每行有 90 个字段(字符串)。问题是如果我从数据库中select *,我的光标会变得非常大(超过 4MB)。并且android中的光标限制为1MB。

我该如何解决这个问题,或者解决这个问题的最优雅的方法是什么? 是否可以将数据库拆分为更小的块并查询出来?

【问题讨论】:

    标签: android android-cursor database-cursor


    【解决方案1】:

    您是否同时需要所有这些行?你能把它们分成几部分吗?这个问题已经被问过好几次了:Android SQLite and huge data sets

    这里还有一个建议:如果您有 90 个字段需要修改,请将它们分成 10 个不同的视图。每个视图都有一个左箭头和右箭头,因此您可以水平遍历屏幕。因此,每个视图将显示 9 个字段。或者类似的策略。本质上,除了列名之外,这些都是相同的视图,因此您不必修改太多代码。

    【讨论】:

    • 是的,我同时需要所有这些行,因为我需要将它们存储在 ArrayList 中以填充和适配列表视图。问题似乎在于存储在游标中的对象的大小而不是行数(在您建议的链接中回答的问题中,行数有问题)
    • 限制适用于整体数据,无论是由于大量行还是非常大的列或许多列。除了以某种方式压缩您的数据之外,我不知道有任何替代方法。
    • 知道如何压缩我的数据吗?我使用 String 来存储它们,因为字符串的大小随着其中的字符数而增长......我不知道还有其他优化方法。
    • 您是否同时需要所有 90 个字段?不能有不同的看法吗?你在使用 CursorAdapter 吗?
    【解决方案2】:

    通常你永远不会选择 *。首先,每一行都有一个唯一标识符,您的用户将只想选择某些行和列 - 即他们可以在 android 屏幕上看到的内容。看起来很粗鲁,这是一个非常基本的问题。您只返回要在手机上为该屏幕显示的列和行 - 否则您会消耗不必要的电池寿命来传输永远不会显示的数据。标准方法是使用参数化存储过程。谷歌参数化存储过程并做一些阅读 - 通过 - 你不能更新任何表,除非你返回该表的唯一行标识符。

    【讨论】:

    • 我必须选择*,因为不幸的是,我需要使用所有字段。用户将编辑一些字段,而其他字段将用于不同的设置。
    • 在这种情况下,我将使用动态 SQL,其中字段名称由用户从复选框列表中选择它们生成,加上您需要更新的任何隐藏字段,然后转到详细视图。你也可以做一个动态更新语句。不过,我仍然不知道您是如何在典型的 android 显示器上获取所有这些数据的。
    【解决方案3】:

    我找到了处理这个问题的方法,我想与所有需要它的人分享。

       int limit = 0;
       while (limit + 100 < numberOfRows) {
           //Compose the statement
           String statement = "SELECT * FROM Table ORDER someField LIMIT '"+ limit+"', 100";
           //Execute the query
           Cursor cursor = myDataBase.rawQuery(statement, null);
           while (cursor.moveToNext()) {
               Product product = new Product();
               product.setAllValuesFromCursor(cursor);
               productsArrayList.add(product);
          }
          cursor.close();
          limit += 100;
     }
    
     //Compose the statement
     String statement = "SELECT * FROM Table ORDER someField LIMIT '"+  (numberOfRows - limit)+"', 100";
     //Execute the query
     Cursor cursor = myDataBase.rawQuery(statement, null);
    
     while (cursor.moveToNext()) {
         Product product = new Product();
         product.setAllValuesFromCursor(cursor);
         productsArrayList.add(product);
     }
     cursor.close();
    

    主要思想是分割你的数据,所以你可以使用游标,因为它应该被使用。如果您有索引表,它在 2 秒内工作 5k 行。

    谢谢, 方舟

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-27
      • 2011-06-18
      相关资源
      最近更新 更多