【问题标题】:How sqlite3 write capacity is calculatedsqlite3 写容量是如何计算的
【发布时间】:2018-09-25 01:22:09
【问题描述】:

我创建测试表

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);

磁盘报告写入 48kb

这比我想象的要大得多,我知道在 sqlite 中整数大小为 4 字节,我认为应该写总小于 10 字节。
第二个写的也接近第一个的大小,所以我更困惑...... 谁能告诉我为什么?谢谢!

【问题讨论】:

    标签: ios iphone sqlite


    【解决方案1】:

    将涉及一些元数据开销。首先将创建数据库文件,该文件必须维护表、索引、序列、自定义函数等的架构。这些都会影响磁盘空间的使用。

    例如,在 Linux 上,将您在上面定义的数据库表添加到新数据库会生成大小为 12288 字节 (12KB) 的文件。如果您使用更多表,空间需求将会增加,就像您向表中添加数据时一样。

    此外,出于效率原因,数据库通常以“页”的形式将数据写入磁盘,即分配一页(或块)空间然后写入。将选择页大小以优化 I/O,例如4096 字节。因此,如果需要新页面,写入单个整数可能需要 4KB 磁盘。但是,您会注意到写入第二个整数不会消耗更多空间,因为现有页面中有足够的可用空间。一旦页面变满时将分配一个新页面,并且磁盘大小可能会增加。

    以上内容有点简化。数据库页面分配和管理策略是一个复杂的课题。我确信搜索会找到许多包含 SQLite 详细信息的资源。

    【讨论】:

    • 其实第二次写的也接近第一次的大小,所以比较迷茫......
    • 这不是我所经历的。需要 527 次相同的提交插入到该表中才能更改文件大小。它高度依赖于数据库引擎的调整,这无疑会在操作系统和环境中有所不同。如果您的数据库文件每次写入增加 48K 字节,那么我会担心。你是说这就是正在发生的事情吗?
    • 在我的项目中,有时需要在表中插入或更新超过 200~500 行,写入速率 5~10MB/s 太快导致 UI 队列阻塞一秒钟。我想了解更多关于sqlite 写做事
    • 看来我误解了你的问题。您在谈论数据传输而不是磁盘空间使用情况。我认为@CL 的answer 更好地解决了这个问题。
    【解决方案2】:

    将每一行单独写入文件对于大型操作来说效率低下,因此数据库总是读取和写入整个页面。

    您的 INSERT 命令至少需要修改三页:表数据、包含 AUTOINCREMENT 计数器的系统表和数据库头中的数据库更改计数器。

    为了使更改即使在中断的情况下也是原子的,数据库需要save the old data of all changed pages in the rollback journal。所以总共有六页。

    如果您没有对这两个命令使用显式事务,则每个命令都会自动包装到一个自动事务中,因此您可以获得两个命令的这些写入。总共有十二页。

    默认页面大小为 4 KB,这是您看到的写入量。 (显然,文件系统元数据的写入没有显示在报告中。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 1970-01-01
      • 2022-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      相关资源
      最近更新 更多