<?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>DuckDB on FXIO 技术博客</title><link>https://fxio.site/tags/duckdb/</link><description>Recent content in DuckDB on FXIO 技术博客</description><generator>Hugo -- 0.157.0</generator><language>zh-cn</language><lastBuildDate>Tue, 04 Aug 2026 11:53:09 +0800</lastBuildDate><atom:link href="https://fxio.site/tags/duckdb/index.xml" rel="self" type="application/rss+xml"/><item><title>同一个「存数据」的需求，为什么长出了三种完全不同的数据库？</title><link>https://fxio.site/posts/ai/2026-08-04-database-three-philosophies/</link><pubDate>Tue, 04 Aug 2026 11:53:09 +0800</pubDate><guid>https://fxio.site/posts/ai/2026-08-04-database-three-philosophies/</guid><description>&lt;h1 id="同一个存数据的需求为什么长出了三种完全不同的数据库"&gt;同一个「存数据」的需求，为什么长出了三种完全不同的数据库？&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;PostgreSQL、Redis、DuckDB——三者都管自己叫「数据库」，但架构几乎没有一处相同。本文从一个问题出发：为什么「存数据」这一件事，需要三种截然不同的答案？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;先说个真实感受：新人问我「该用什么数据库」时，我最怕听到的是「就……存点数据」。因为「存数据」这个需求背后，至少藏着三个互相矛盾的目标：&lt;strong&gt;要快（延迟）、要对（一致性）、要能算（分析吞吐）&lt;/strong&gt;。这三个目标在物理层面就是打架的，所以业界长出了三种完全不同形态的数据库，各自押注一个目标。&lt;/p&gt;
&lt;p&gt;这篇拿 PostgreSQL（75K+ Star 里的常青树）、Redis（75K Star）、DuckDB（40K Star）当样本——它们恰好是三条路线的教科书级代表。&lt;/p&gt;
&lt;h2 id="三种数据库三种世界观"&gt;三种数据库，三种「世界观」&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;PostgreSQL&lt;/th&gt;
&lt;th&gt;Redis&lt;/th&gt;
&lt;th&gt;DuckDB&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;一句话定位&lt;/td&gt;
&lt;td&gt;数据的基础设施&lt;/td&gt;
&lt;td&gt;远程数据结构接口&lt;/td&gt;
&lt;td&gt;SQLite for Analytics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;押注的目标&lt;/td&gt;
&lt;td&gt;正确性 &amp;gt; 性能&lt;/td&gt;
&lt;td&gt;延迟 &amp;gt; 一切&lt;/td&gt;
&lt;td&gt;分析吞吐 + 零部署&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数据在哪&lt;/td&gt;
&lt;td&gt;磁盘（缓冲进内存）&lt;/td&gt;
&lt;td&gt;内存&lt;/td&gt;
&lt;td&gt;就在文件里（CSV/Parquet/S3）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;并发模型&lt;/td&gt;
&lt;td&gt;多进程、MVCC 多版本&lt;/td&gt;
&lt;td&gt;单线程事件循环&lt;/td&gt;
&lt;td&gt;单写者、Morsel 并行读&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;典型场景&lt;/td&gt;
&lt;td&gt;金融、ERP、订单&lt;/td&gt;
&lt;td&gt;缓存、会话、排行榜、限流&lt;/td&gt;
&lt;td&gt;数据科学家本地跑 SQL 分析&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;注意：这三行的每一列差异都不是「实现细节」，全是&lt;strong&gt;世界观分歧&lt;/strong&gt;。往下看。&lt;/p&gt;
&lt;h2 id="postgresql把正确放在所有选项的前面"&gt;PostgreSQL：把「正确」放在所有选项的前面&lt;/h2&gt;
&lt;p&gt;PostgreSQL 从 1986 年 Berkeley 的学术项目走到今天，38 年没死，靠的不是快——它从来不追求最快。它的护城河是&lt;strong&gt;正确性和可信度的复利&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;几个能看出价值观的设计：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Process-per-connection：每个连接一个独立进程。&lt;/strong&gt; MySQL（InnoDB）用线程池，PG 用进程。进程更重、启动更慢，但一个连接崩了不会带走别人——内存隔离是操作系统保证的，不是代码纪律保证的。这是「可靠性高于便利」的字面体现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. MVCC 的代价是 VACUUM。&lt;/strong&gt; 读写互不阻塞的代价是旧版本数据堆在表里，得靠 VACUUM 回收。很多人骂 VACUUM 烦，但这笔交易是明码标价的：读永远不阻塞写、写永远不阻塞读，换来的运维成本。对比 MySQL undo log 的回收方式，各有取舍，但 PG 把旧版本直接放主表的设计，让「时间旅行」「闪回查询」这类能力成为可能。&lt;/p&gt;</description></item></channel></rss>