【发布时间】:2014-12-05 01:47:10
【问题描述】:
我在 Android 上保存了一个大型数据库。有很多行,行的大小有些可变。如何在运行时确定内存数据库的大小?
【问题讨论】:
-
@madlymad , Max size of an Android app's in-memory SQLite database? 询问数据库可以有多大。我在问数据库有多大。
我在 Android 上保存了一个大型数据库。有很多行,行的大小有些可变。如何在运行时确定内存数据库的大小?
【问题讨论】:
在 SQLite 中,内存数据库被实现为没有后备文件的页面缓存。
SQLite C API 允许使用sqlite3_db_status(SQLITE_DBSTATUS_CACHE_USED) 或sqlte3_status(SQLITE_STATUS_PAGECACHE_USED) 等函数获取状态。
但是,Android 数据库 API 不提供对这些函数的访问权限。
【讨论】:
好的,这是我想出的解决方案。它不漂亮,但它有效。
Android 的SQLiteDatabase 类包括一个设置最大数据库大小的方法setMaximumSize(long numBytes)。最大尺寸不能设置为低于当前尺寸。所以解决办法就是把最大大小设置为页面文件大小,看方法返回什么大小。这是我的SQLiteOpenHelper 类中的方法:
public synchronized int getDatabaseUsage() {
SQLiteDatabase db = getWritableDatabase();
long pageSize = db.getPageSize();
long savedMaximumSize = db.getMaximumSize();
long appliedSize = db.setMaximumSize(pageSize);
int percentageUsed = (int) ((appliedSize * 100) / savedMaximumSize);
db.setMaximumSize(savedMaximumSize);
Log.v(LOG_TAG, "Percentage database space used: " + percentageUsed);
return percentageUsed;
}
我将最大大小设置为设备的大内存类:
private static final long BYTES_IN_A_MEGABYTE = 1048576;
/**
* Maximum size of the database in bytes
*/
private final long mMaxSize;
public SQLHelper(Context context) {
super(context, null, null, DATABASE_VERSION);
mMaxSize = BYTES_IN_A_MEGABYTE * Helper.getLargeMemoryClass(context);
}
public void onCreate(SQLiteDatabase db) {
<database creation code>
db.setMaximumSize(mMaxSize);
}
然后我只是在每次批量插入之前检查数据库使用情况。如果使用量超过 50,我会从表中删除旧行并运行 Vacuum 命令以回收空间。
/**
* Rebuilds the entire database.
* <p/>
* This reclaims empty space left behind after deletions.
*/
public void vacuum(SQLiteDatabase db) {
db.execSQL("VACUUM");
}
【讨论】: