<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Sqlite on LeafCxy's Blog</title><link>https://leafcxy.github.io/tags/sqlite/</link><description>Recent content in Sqlite on LeafCxy's Blog</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 19 Jul 2025 02:57:26 +0000</lastBuildDate><atom:link href="https://leafcxy.github.io/tags/sqlite/index.xml" rel="self" type="application/rss+xml"/><item><title>sqlite删除记录后数据库文件大小不变</title><link>https://leafcxy.github.io/posts/2025-07-19-3/</link><pubDate>Sat, 19 Jul 2025 02:57:26 +0000</pubDate><guid>https://leafcxy.github.io/posts/2025-07-19-3/</guid><description>&lt;p&gt;最的做的项目中要有到sqlite数据存储，写了测试程序进行测试，存入300万条记录，占用flash大小为 86.1M，当把表中的记录全部删除后发后数据库文件大小依然是 86.1M；&lt;/p&gt;
&lt;p&gt;原因是：
sqlite采用的是变长纪录存储，当你从Sqlite删除数据后，未使用的磁盘空间被添加到一个内在的”空闲列表”中用于存储你下次插入的数据，用于提高效率，磁盘空间并没有丢失，但也不向操作系统返回磁盘空间，这就导致删除数据乃至清空整个数据库后，数据文件大小还是没有任何变化，还是很大&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;解决方法：两种&lt;/p&gt;
&lt;h2 id="在数据删除后手动执行vacuum命令执行方式很简单"&gt;在数据删除后，手动执行VACUUM命令，执行方式很简单&lt;/h2&gt;
&lt;p&gt;sqlite&amp;gt; vacuum；&lt;/p&gt;
&lt;p&gt;VACUUM命令会清空“空闲列表”，把数据库尺寸压缩到最小。但是要耗费一些时间。&lt;/p&gt;
&lt;p&gt;FQA里面说，在Linux的环境下，大约0.5秒/M。并且要使用两倍于数据库文件的空间。&lt;/p&gt;
&lt;p&gt;我憎恨此FQA，他只说系统环境，不说机器硬件环境。我在测试手机上执行用了将近13秒时间压缩了将近3M的空间。至于它所占用的另一部分空间，是生成了一个.db-journal后缀名的临时文件。（这个问题对我现在来说是无所谓的。）&lt;/p&gt;
&lt;h2 id="在数据库文件建成中将auto_vacuum设置成1"&gt;在数据库文件建成中，将auto_vacuum设置成“1”&lt;/h2&gt;
&lt;p&gt;注意：只有在数据库中未建任何表时才能改变auto-vacuum标记。试图在已有表的情况下修改不会导致报错。&lt;/p&gt;
&lt;p&gt;cmd.CommandText = &amp;ldquo;PRAGMA auto_vacuum = 1;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;cmd.ExecuteNonQuery()&lt;/p&gt;
&lt;p&gt;当开启auto-vacuum，当提交一个从数据库中删除除数据的事物时，数据库文件自动收缩。&lt;/p&gt;
&lt;p&gt;数据库会在内部存储一些信息以便支持这一功能，这使得数据库文件比不开启该选项时稍微大一些。&lt;/p&gt;
&lt;p&gt;我的表结构，不含任何数据是，数据库文件大小是25K左右，开了auto_vacuum之后是26K。&lt;/p&gt;
&lt;p&gt;插入运行基础数据后，文件变成35K，开了auto_vacuum之后是36K。&lt;/p&gt;
&lt;p&gt;变化不大，无所谓。&lt;/p&gt;
&lt;p&gt;但是第二个方法同样有缺点，只会从数据库文件中截断空闲列表中的页， 而不会回收数据库中的碎片，也不会像VACUUM 命令那样重新整理数据库内容。实际上，由于需要在数据库文件中移动页， auto-vacuum 会产生更多的碎片。而且，在执行删除操作的时候，也有那个.db-journal文件产生。&lt;/p&gt;
&lt;p&gt;要使用auto-vacuum，需要一些前题条件。 数据库中需要存储一些额外的信息以记录它所跟踪的每个数据库页都找回其指针位置。 所以，auto-vacumm 必须在建表之前就开启。在一个表创建之后， 就不能再开启或关闭 auto-vacumm。&lt;/p&gt;
&lt;p&gt;其实按照运行时间上的比较，两个在做了大删除操作后，从3M变到35K的时间其实差不多，执行VACUUM命令稍微长一点，但是也长不了多少，相对而言，这种一点点的长可以忽略不计。&lt;/p&gt;
&lt;p&gt;加上AUTO的方式对碎片的造成情况，如果数据交换次数多的话，这种方式很不合适。&lt;/p&gt;</description></item><item><title>sqlite获取插入id的几种方式</title><link>https://leafcxy.github.io/posts/2025-07-19-2/</link><pubDate>Sat, 19 Jul 2025 02:48:46 +0000</pubDate><guid>https://leafcxy.github.io/posts/2025-07-19-2/</guid><description>&lt;p&gt;SQLite 中，表设置自增列后，可通过如下几种方式获取插入记录的 ID&lt;/p&gt;
&lt;h2 id="sqlite_sequence"&gt;sqlite_sequence&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;insert&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;into&lt;/span&gt; TbTest(Name, Age) &lt;span style="color:#66d9ef"&gt;values&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;usr&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; seq &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; sqlite_sequence &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;TbTest&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- more --&gt;
&lt;h2 id="rowid"&gt;rowid&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;--表设置了自增列，会生成 rowid 的隐藏列，需要显式查询语句才可以查询出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; rowid &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; TbTest;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;--但是，表没有设置自增列，上面的语句无法查出任何值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;--特殊的，表无论是否设置了自增列，但都可以使用聚合函数查询出 rowid
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;insert&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;into&lt;/span&gt; TbTest(Name, Age) &lt;span style="color:#66d9ef"&gt;values&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;usr&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;max&lt;/span&gt;(rowid) &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; TbTest;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="id列"&gt;ID列&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;insert&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;into&lt;/span&gt; TbTest(Name, Age) &lt;span style="color:#66d9ef"&gt;values&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;usr&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;max&lt;/span&gt;(ID) &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; TbTest;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="last_insert_rowid"&gt;last_insert_rowid&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;insert&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;into&lt;/span&gt; TbTest(Name, Age) &lt;span style="color:#66d9ef"&gt;values&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;usr&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;--注意！若此行处有插入临时表的操作，下面的语句获取到的是插入临时表的 rowid
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; last_insert_rowid() &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; TbTest &lt;span style="color:#66d9ef"&gt;LIMIT&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item></channel></rss>