Flutter中如何获取数据库总大小及指定数据表的大小?
我明白你想要的是数据库和表的实际存储大小,而不是行数——之前用COUNT(*)确实只能拿到记录数量,和占用的磁盘空间完全是两回事。下面我给你分享在Flutter sqflite环境下的正确实现方法:
获取数据库总大小
SQLite数据库本质上是单个磁盘文件(默认配置下),所以直接获取这个文件的字节数就能得到数据库的总大小,包含所有表、索引、日志等内容。
实现代码
import 'dart:io'; import 'package:sqflite/sqflite.dart'; Future<int> getDatabaseTotalSize(String dbName) async { // 获取数据库存储的根目录 String dbDirectory = await getDatabasesPath(); // 拼接数据库文件的完整路径 String fullDbPath = '$dbDirectory/$dbName'; File dbFile = File(fullDbPath); if (await dbFile.exists()) { // 返回文件的字节大小 return await dbFile.length(); } return 0; // 数据库不存在时返回0 } // 使用示例 void main() async { int totalBytes = await getDatabaseTotalSize('dummy.db'); // 转换成更易读的MB单位 double totalMB = totalBytes / 1024 / 1024; print('数据库总大小:${totalMB.toStringAsFixed(2)} MB'); }
获取指定数据表的大小
SQLite没有直接返回单表大小的内置函数,但可以通过查询系统虚拟表来估算或精确计算,这里提供两种可靠的方法:
方法一:基于sqlite_stat1的估算(通用、轻量)
SQLite的sqlite_stat1表存储了表的统计信息,其中包含表占用的页面数,结合数据库的页面大小就能计算出表的大致尺寸。
实现代码
Future<int> getTableSize(Database db, String tableName) async { // 获取数据库的页面大小(默认通常是4KB,但不同配置可能不同) int pageSize = Sqflite.firstIntValue(await db.rawQuery('PRAGMA page_size')) ?? 4096; // 查询目标表的页面数:sqlite_stat1的stat列第一个值就是页面数 var statResult = await db.rawQuery( 'SELECT stat FROM sqlite_stat1 WHERE tbl_name = ?', [tableName] ); if (statResult.isNotEmpty) { // 拆分stat字符串,提取页面数字 int pageCount = int.parse(statResult.first['stat'].toString().split(' ')[0]); // 页面大小 × 页面数 = 表的大致大小 return pageSize * pageCount; } return 0; // 表不存在时返回0 } // 使用示例 void main() async { var db = await openDatabase('dummy.db'); int tableBytes = await getTableSize(db, 'dummyTable1'); double tableKB = tableBytes / 1024; print('dummyTable1大小:${tableKB.toStringAsFixed(2)} KB'); await db.close(); }
方法二:基于dbstat的精确计算(实时、准确)
dbstat是SQLite的虚拟表,可以实时统计每个表、索引甚至单个页面的占用空间,结果更精确,但部分旧版本SQLite可能需要先启用。
实现代码
Future<int> getTableSizeDetailed(Database db, String tableName) async { // 启用dbstat虚拟表(部分环境可能不需要此步骤,但加上更稳妥) await db.rawQuery('PRAGMA enable_dbstat = on;'); // 统计目标表所有相关页面的总大小 int? totalSize = Sqflite.firstIntValue(await db.rawQuery( 'SELECT sum(pgsize) FROM dbstat WHERE name = ?', [tableName] )); return totalSize ?? 0; }
注意事项
- 两种方法返回的都是字节数,你可以根据需求转换成KB/MB等单位
sqlite_stat1的统计值可能会有延迟(依赖SQLite的自动分析),如果需要实时精确值,优先用dbstat方法- 如果表包含索引,两种方法都会把索引的大小包含在内,若只想统计纯数据大小,可以调整
dbstat的查询条件(比如加上WHERE type = 'table')
内容的提问来源于stack exchange,提问作者NaanAvanAlla
相关产品推荐
相关产品推荐

