我创建测试表
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字节,我认为应该总写不到10Byte。
第二次写也接近第一次写的大小,所以我更加困惑......
有人可以告诉我为什么吗?谢谢!
答案 0 :(得分:1)
将每一行单独写入文件对于较大的操作来说效率低,因此数据库总是读写整个页面。
您的INSERT命令需要至少修改三个页面:表数据,包含AUTOINCREMENT计数器的系统表以及数据库头中的数据库更改计数器。
即使在中断的情况下也要使更改成为原子,数据库需要save the old data of all changed pages in the rollback journal。这总共六页。
如果不在两个命令周围使用显式事务,则每个命令都会自动包装到自动事务中,因此您可以为这两个命令获取这些写入。那是整整12页。
默认页面大小为4 KB,这是您看到的写入量。 (显然,文件系统元数据的写入不会显示在报告中。)
答案 1 :(得分:0)
将涉及一些元数据开销。首先,将创建数据库文件,该文件必须维护表,索引,序列,自定义函数等的模式。这些都有助于磁盘空间的使用。
例如,在Linux上将上面定义的数据库表添加到新数据库会生成大小为12288字节(12KB)的文件。如果您有更多的表,则空间需求将会增加,就像向表中添加数据时一样。
此外,出于效率原因,数据库通常在“页面”中将数据写入磁盘,即分配然后写入空间的页面(或块)。将选择页面大小以优化I / O,例如因此,如果需要新的页面,写一个整数可能需要4KB磁盘。但是,您会注意到写第二个整数不会消耗更多空间,因为现有页面中有足够的可用空间。变满了将分配新页面,磁盘大小可能会增加。
以上是一点简化。数据库页面分配和管理的策略是一个复杂的主题。我确信搜索会找到许多资源,其中包含SQLite的详细信息。