所有文章

2026-10-23

· Dylan Yu
SQLiteDuckDB数据库数据分析

SQLite 还是 DuckDB:2026 年本地数据库怎么选

SQLite 和 DuckDB 都是嵌入式、零服务器、单文件数据库——而且它们各自擅长对方不擅长的东西。这里给你一套基于实际需求的选择框架。

如果你这两年关注数据库世界,会看到一个奇怪的现象:2020 年代最有趣的两个数据库都是嵌入式的。不用装服务器、不用跑守护进程、不用连远程主机的连接串。它们是链接进你进程的库,读写你磁盘上的一个文件。

SQLite 不用说——二十年来它就是嵌入式数据库的默认选择,历史上装在设备上最多的数据库就是它。但新来者是 DuckDB,一个嵌入式分析引擎,当人们意识到可以在单个文件上、零基础设施地跑一个列式、向量化的 OLAP 数据库时,它就爆炸式流行了。

让人困惑的是它们从外面看几乎一模一样。都是"一个能用 SQL 查询的文件"。都是零安装。数据工程师、ML 从业者和独立开发者都在用。然而它们为完全不同的工作做了优化——选错意味着和数据库搏斗而不是使用它。给你一套真正有用的框架。

一句话区别

SQLite 是 OLTP 数据库:为事务而生——大量小读小写、单行查找、需要在单机上有一个持久、可查询存储的应用。

DuckDB 是 OLAP 数据库:为分析而生——大扫描、数百万行上的聚合、大表间的连接、一次从大量数据中算出答案的查询。

这就是全部区别,几乎其它一切——性能特征、用例、失败模式——都由此而来。

SQLite 赢在哪里

SQLite 是行式存储,为应用数据库的工作负载做了优化:按键找行、插行、改行、提交。为此调优了 25 年,效果明显。

它是应用的正确数据库。 如果你在构建本地优先应用——桌面工具、移动应用、插件、游戏、笔记应用,任何数据存在用户机器上的东西——SQLite 就是答案。它处理并发读和单写事务,带 ACID 保证,内嵌在每个操作系统里,是数据库世界里经过最多实战考验的代码。你应用的运营数据——应用逻辑不断读写的那批订单、用户、设置和状态——属于 SQLite。

它是所有小型数据库里生态最好的。 每种语言都有一等驱动。每个平台都有 GUI 工具。它是 iOS、Android、浏览器(IndexedDB 的引擎)和大多数桌面框架的默认。你选 SQLite 不是因为花哨,而是因为它无处不在、就是能用。

它很适合做应用的事实来源。 对我来说这是关键用例:SQLite 是你应用的当前状态所在——你的代码每天读写的那些行。它是你应用运行在其上的数据库,不是用来跑报表的数据库。

DuckDB 赢在哪里

DuckDB 是列式、向量化引擎。它不是把行连续存储然后扫描,而是按列存储,利用现代 CPU 向量化,在笔记本上每秒处理数百万行。这个设计让它成为糟糕的 OLTP 数据库和出色的分析引擎。

它是做分析的正确数据库。 如果你在做数据工作——查询大 CSV、探索 Parquet 文件、聚合日志、对一年的事件算指标、搭本地数据管道——DuckDB 就是答案。它原地查询文件:你可以不导入任何东西,直接对 CSV 或 Parquet 文件跑 SQL,这是让它成为"我有一个大文件,我需要答案"默认工具的那个特性。

它为现代数据栈而生。 Parquet、Arrow、Polars、Pandas——DuckDB 都能嵌进去。你可以把 Parquet 文件加载进 DuckDB 表,或直接查询它,或把查询结果写回 Parquet。对数据工程师来说,这是最接近瑞士军刀的东西。

它是作为计算器的 SQL,不是作为存储的 SQL。 心智模型不同:用 DuckDB 你通常是在计算什么——"这 4000 万个事件的平均会话时长是多少?"——而不是在存储什么。所以它是列式的:列式存储擅长快速读取同一列的许多值,而聚合做的正是这件事。

令人困惑的中间地带:SQLite 上跑小分析,或 DuckDB 上跑应用?

这里是建议变得模糊的地方,我想说精确一点。

"我就用 SQLite 做分析吧——更简单。" 可以,数据小的时候没问题。但一旦你的分析触及几十万行或连接几张表,行式设计就开始让你付代价。在 SQLite 里对一百万行做 GROUP BY 很慢,不是因为 SQLite 差,而是因为它一行行地读,而列式引擎一列列地读。如果你的"快速分析"习惯正在长成真正的工作负载,DuckDB 会用同样的 SQL 快一个数量级。

"DuckDB 能当我的应用数据库吗?" 技术上可以——它支持事务和写入。实际上别。DuckDB 为批量操作而生;逐行写和点查正是它最不擅长的。一个在 DuckDB 上频繁小读小写的应用会感到一种 SQLite 永远不会有的迟缓。用对的工具:SQLite 存应用状态,DuckDB 分析它。

真正奏效的模式:两个都用

大家错过的是这一点:它们不是竞争对手,是一条流水线。2026 年我见到最常见的好配置是:

  1. SQLite 是你应用的事实来源。 当前状态——订单、用户、配置——住在 SQLite 里,由你的应用事务性地写入。
  2. DuckDB 分析它。 你把 DuckDB 指向 SQLite 文件——它可以通过 sqlite 扩展直接读 SQLite 数据库——跑那些重的聚合、连接、同比比较。数百万行,笔记本速度,零基础设施。

没有导出步骤。没有 ETL。没有第二台服务器。分析引擎原地读应用数据库。老实说,这是两者合一的杀手级用例。

同样的模式可以泛化:DuckDB 也原地读 Parquet 和 CSV,所以它变成"查询我拥有的一切,不管它住在哪"的单一工具,而 SQLite 保持"存储我应用需要的状态"的单一工具。

怎么决定:三个问题

按顺序问自己这三个问题,每次都会落在正确的那个上。

1. 这些数据是否被应用整天逐行地读写? 是 → SQLite。那是 OLTP 负载,正是 SQLite 的用途。如果否——它是一个你在分析的文件——进入问题 2。

2. 你的查询是否主要是对大量行的聚合、扫描和连接? 是 → DuckDB。那是 OLAP 负载,正是 DuckDB 的用途。GROUP BY、窗口函数、大读取——DuckDB 在这些上会让行式存储难堪。

3. 数据是否很小、查询是否简单? 那老实说哪个都行——如果它有可能变成应用数据库就选 SQLite,如果数据是不断到来的文件(CSV/Parquet)就选 DuckDB。对真正小的分析,差别是噪音;对任何会增长的东西,差别是结构性的。

这对你的本地工具意味着什么

对你使用这些文件的方式有一个实际后果,这是作为 Basevolt(一个桌面数据库工具)的构建者最关心的部分。工具和引擎一样重要。一个能让你浏览、编辑、在 .db 文件上建关系的 SQLite GUI,对模式的应用数据库那一半必不可少。一个把 DuckDB 指向你文件的笔记本或 CLI 处理分析那一半。知道自己在哪一半,就知道该拿哪个工具——以及哪个引擎。

如果你在存应用状态,别再试图让分析工具做存储,留在 SQLite。如果你在分析数据,别再试图让行式存储做分析,让 DuckDB 去扫描。你的栈的两半会在各自做自己该做的活的那一刻停止跟你作对。

BasevoltBasevolt

试试 Basevolt —— 免费的本地优先数据库管理面板,支持 PostgreSQL、MySQL、SQLite 和 Cloudflare D1。

免费下载 Basevolt