You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 04:28:16