Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

使用 SQLite 构建基本缓存

Posted on 2026-04-29

这个网站是静态网站,是用我自己编写的静态网站生成器搭建的。我在本地开发网站时,希望它能快速加载。网站规模相对较小,现在的电脑性能都很强大,所以我不想浪费时间等待。渲染所有 HTML 页面大约需要 15 秒——速度慢到每次都能感觉到延迟。

我使用 Jekyll 时,启用 Jekyll 缓存后速度提升显著。很多耗时的计算其实不需要每次建站都重复执行——例如,将一段 Markdown 代码转换为 HTML 只需执行一次,即可永久缓存。

由于我不再使用 Jekyll,所以我用一个基本的 SQLite 缓存替换了 Jekyll 缓存。我选择 SQLite 是因为它速度快、易于使用,而且可以与Python 标准库一起使用。

每个缓存条目都包含三个部分:命名空间、键和值。命名空间将来自同一操作的所有条目分组,键标识单个条目,值是耗时计算的输出结果。例如,在我的 Markdown 转 HTML 缓存中,命名空间是convert_markdown ,键是输入的 Markdown 文件,值是输出的 HTML 文件。

目前我只存储基本的字符串值。我可以将结构化数据存储为 JSON 或其他格式,但我目前还没有这个需求。

我的缓存实现是用 Python 编写的,但它只是对 SQLite 查询的一个简单封装。

SQLite 查询

创建一个空缓存:

 CREATE TABLE IF NOT EXISTS cache_entries ( namespace , key , value , date_saved , PRIMARY KEY ( namespace , key ) )

这将创建一个名为cache_entries的空表,包含四列:之前提到的命名空间/键/值对,以及用于调试的date_saved列。我原本以为记录缓存条目的保存时间会很有用,但目前为止还没用到。

复合PRIMARY KEY确保对于给定的命名空间/键对,我只有一个缓存条目。

为了存储缓存条目,我使用标准的 SQL INSERT OR REPLACE语句:

 INSERT OR REPLACE INTO cache_entries VALUES ( ? , ? , ? , ? );

要检索缓存条目,我使用标准的SELECT :

 SELECT value FROM cache_entries WHERE namespace =? AND key =? ;

我发现,如果缓存值很大,这个查询会明显变慢,因为 SQLite 需要读取很多页才能检索到该值。有时我只想知道某个值是否被缓存,并不需要知道它的具体内容——缓存条目的存在本身就能让我跳过一些操作。

我还有另一个查询来检测缓存中是否存在匹配的条目,这个查询速度快得多,因为它跳过了读取值这一步:

 SELECT EXISTS ( SELECT 1 FROM cache_entries WHERE namespace =? AND key =? )

最后,我还有几个查询语句用于清除缓存——既可以清除单个条目,也可以清除整个操作:

 DELETE FROM cache_entries WHERE namespace =? AND key LIKE ? ; DELETE FROM cache_entries WHERE namespace =? ;

选择缓存键

对于较小的输入,我将输入用作缓存键。

对于大型输入(例如整篇博客文章的 Markdown 内容),我使用 MD5 哈希值作为键,而不是原始输入。这可以减少写入磁盘的数据量,从而加快数据库速度。SQLite 使用 4KB 的页面,这比我的许多博客文章都要小。一个 4KB 的页面可以存储大量的 MD5 哈希值,而一篇原始博客文章则需要占用多个页面。这部分逻辑是在缓存代码之外处理的。

当结果依赖于外部文件(例如渲染模板)时,我会将该外部文件的最后修改时间包含在缓存键中。当外部文件发生更改时,会发生缓存未命中,需要重新计算结果。

进展如何

如果你感兴趣的话,我的缓存实现是公开的,测试也是公开的。

缓存机制需要一些微调。缓存失效向来是个难题,而且我确实经常没能正确地使缓存失效。在构建网站的正式版本时,我会删除现有的缓存并重新开始,以避免缓存条目过期。

对于本地开发而言,这无疑是一项巨大的进步。以前重新渲染所有 HTML 页面大约需要 15 秒,但有了热缓存后,只需 0.06 秒。速度提升了 200 倍,每次点击保存按钮我都能明显感受到,这让网站开发体验更加流畅、更加令人满意。

[如果您的RSS阅读器中此文章的格式显示异常,请访问原文]

原文: https://alexwlchan.net/2026/sqlite-cache/?ref=rss

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • A List Apart
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Alin Panaitiu
  • Anil Dash
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Big Technology
  • Bits about Money
  • Brandon Skerritt
  • Brent Simmons
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • eighty twenty
  • Elad Gil
  • Ellie Huxtable
  • Ethan Dalool
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • HeardThat Blog
  • Henrique Dias
  • Herman Martinus
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Li Haoyi
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Maggie Appleton
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mind Matters
  • Mostly metrics
  • Naval Ravikant
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • PostHog
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Rohit Patel
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Slava Akhmechet
  • Small Good Things
  • Steph Ango
  • Stephen Wolfram
  • Steve Blank
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • Wes Kao
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2026 搞英语 → 看世界 | Design: Newspaperly WordPress Theme