SQLite CursorWindow 限制 - 如何避免崩溃

4

我需要执行一个查询并将结果存储在一个列表中,我使用的函数是:

List<SpoolInDB> getSpoolInRecords(String label, boolean getLastInserted) {
    List<SpoolInDB> spoolInList = new ArrayList<>();
    try {
        if (mdb == null)
            mdb = mdbHelper.getWritableDatabase();

        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(TABLE_SPOOLIN);

        Cursor c = qb.query(mdb, null, " label='" + label + "'", null, null, null, " dateins " + (getLastInserted ? "desc" : "asc"));
        if (c != null) {
            c.moveToFirst();
            if (c.getCount() > 0) {
                int ndxid = c.getColumnIndex("id");
                int ndxserverID = c.getColumnIndex("serverID");
                int ndxlabel = c.getColumnIndex("label");
                int ndxvalue = c.getColumnIndex("value");
                int ndxpriority = c.getColumnIndex("priority");
                int ndxdateins = c.getColumnIndex("dateins");

                do {
                    SpoolInDB spoolIn = new SpoolInDB();
                    spoolIn.setId(c.getString(ndxid));
                    spoolIn.setServerID(c.getString(ndxserverID));
                    spoolIn.setLabel(c.getString(ndxlabel));
                    spoolIn.setValue(c.getString(ndxvalue));
                    spoolIn.setPriority(c.getString(ndxpriority));
                    spoolIn.setDateins(c.getString(ndxdateins));
                    spoolInList.add(spoolIn);

                } while (c.moveToNext());
            }
            c.close();
        }
    } catch (Exception e) {
        wil.WriteFile("4)DbGest - Exception: " + e.toString());
    }
    return spoolInList;
}

在正常情况下,此函数能够完美运行,但在某些情况下,该函数会产生异常:
Window is full: requested allocation 3209815 bytes, free space 2096647 bytes, window size 2097152 bytes

这个问题是因为在“values”字段中,我可以存储一些json数据,有时可能会大于2mb。我无法预测何时数据会大于2mb,我需要一个始终有效的解决方案。

我该如何解决我的问题?

1个回答

6

CursorWindow 的大小限制目前为 2MB。如果单行数据的大小超过 2MB,就无法将其放入 Cursor 中进行读取。

因此,不要将整个 JSON 存储为单个元素,而是可以解析它并将其存储在数据库中的单独列或表中。

这样做的好处有:

  1. 可以从保存到数据库中的 JSON 数据中保留不需要的信息。
  2. 可以一次只查询部分数据(少数列),以避免查询结果超过 2MB 的 CursorWindow 限制。

或者您可以尝试其他数据库系统,如 Realm(我没有尝试过,所以不确定是否存在任何限制)。


1
感谢您的回答。我想这是使用SQLIte和大型JSON的正确方式。关于Realm:我一直在从Realm迁移到SQLite,并处理大型GeoJson字段(> 5 MB)。Realm在保存大型GeoJSON时存在限制,而SQLite则适用于检索。 - sugaith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接