提问人:Karim 提问时间:4/15/2018 最后编辑:Karim 更新时间:4/15/2018 访问量:100
如何计算 sqlite3 写入容量
How sqlite3 write capacity is calculated
问:
我创建测试表
create table if not exists `HKDevice` (primaryID integer PRIMARY KEY AUTOINCREMENT,mac integer)
插入 1 行:
NSString *sql = @"insert into `HKDevice` (mac)values('0')";
int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, &errorMesg);
这比我想象的要大得多,我知道 sqlite 中的整数大小为 4 字节,我认为应该写总量小于 10 字节。
第二次写也接近第一次的大小,所以我比较困惑......
有人能告诉我为什么吗?谢谢!
答:
将涉及一些元数据开销。首先,将创建数据库文件,该文件必须维护表、索引、序列、自定义函数等的模式。这些都会影响磁盘空间的使用。
例如,在 Linux 上,将上面定义的数据库表添加到新数据库将生成大小为 12288 字节 (12KB) 的文件。如果表更多,空间需求将增加,就像向表添加数据时一样。
此外,出于效率原因,数据库通常以“页”的形式将数据写入磁盘,即分配一页(或块)空间,然后写入其中。将选择页面大小以优化 I/O,例如 4096 字节。因此,如果需要新页面,写入单个整数可能需要 4KB 的磁盘。但是,您会注意到,写入第二个整数不会占用更多空间,因为现有页面中有足够的可用空间。页面已满后,将分配一个新页面,并且磁盘大小可能会增加。
以上是有点简化。数据库页面分配和管理策略是一个复杂的主题。我敢肯定,搜索会找到许多包含SQLite详细信息的资源。
评论
对于较大的操作,将每一行单独写入文件效率低下,因此数据库始终读取和写入整个页面。
INSERT 命令至少需要修改三页:表数据、包含 AUTOINCREMENT 计数器的系统表和数据库头中的数据库更改计数器。
为了使更改即使在中断的情况下也能实现原子化,数据库需要将所有已更改页面的旧数据保存在回滚日志中。总共有六页。
如果不对这两个命令使用显式事务,则每个命令都会自动包装到自动事务中,因此您可以同时获得这两个命令的这些写入。总共有十二页。
默认页面大小为 4 KB,这是您看到的写入量。 (显然,文件系统元数据的写入不会显示在报告中。
上一个:SQLITE数据库上传
下一个:FMDB数据插入时间
评论