DuckDB 生态深度拆解:从「分析领域的 SQLite」到 SQL 原生湖仓——DuckLake、Quack 协议与异步 I/O 如何重新定义嵌入式分析的边界
引言:一个正在「吞噬」数据基础设施的嵌入式数据库
2026 年的数据工程世界,有一个名字正在以惊人的速度渗透进每一个角落——DuckDB。
这个被称为「分析领域的 SQLite」的嵌入式列式数据库,GitHub Star 数已突破 39.9K,在短短几年内从一个学术项目成长为数据分析、ETL、湖仓架构的事实标准。但如果你还停留在「DuckDB 只是一个本地 OLAP 查询工具」的认知上,那你已经严重低估了它的野心。
2026 年 4 月至 7 月,DuckDB 生态连续发布三大里程碑式更新:
- DuckLake v1.0(2026-04-13):一个用 SQL 作为元数据存储的湖仓格式,直接挑战 Delta Lake 和 Apache Iceberg 的统治地位
- Quack 协议(2026-05-12):DuckDB 自己的客户端-服务器协议,让多个 DuckDB 实例可以互相「对话」,终结了嵌入式数据库无法多写的历史
- 异步 I/O 架构重写(2026-07-31):「Work, Thread, Work」三阶段异步模型,让 DuckDB 的 I/O 性能提升了一个数量级
这三把火,正在把 DuckDB 从一个「好用的本地工具」变成一个完整的数据基础设施平台。今天,我们来深度拆解这三大核心架构,看看它们是如何协作的,以及它们对数据工程意味着什么。
一、DuckDB 回顾:为什么是嵌入式 OLAP?
在深入新特性之前,我们先快速回顾 DuckDB 的核心定位。
1.1 SQLite for Analytics 的设计哲学
SQLite 是 OLTP 领域的嵌入式王者,DuckDB 的设计者 Hannes Mühleisen 和 Mark Raasveldt 受到了同样的启发:能否为分析型工作负载(OLAP)做一个类似的嵌入式数据库?
DuckDB 的核心设计决策:
| 特性 | 传统 OLAP (ClickHouse/Druid) | DuckDB |
|---|---|---|
| 架构 | 客户端-服务器 | 进程内(In-Process) |
| 依赖 | 数十到数百个 | 零依赖 |
| 存储 | 专用存储格式 | 直接查询 Parquet/CSV/JSON |
| 部署 | 集群部署 | 单二进制,嵌入应用 |
| SQL 标准 | 各有各的方言 | 高度标准兼容 |
# DuckDB 的使用方式和 SQLite 一样简单
import duckdb
# 直接查询 Parquet 文件,无需导入
result = duckdb.sql("""
SELECT customer_id, SUM(amount) as total_spent
FROM read_parquet('orders/*.parquet')
GROUP BY customer_id
ORDER BY total_spent DESC
LIMIT 20
""").df()
这种「零配置、直接查询文件」的体验,让 DuckDB 迅速成为数据科学家和分析师的宠儿。但嵌入式架构也有天然的限制:多进程无法同时写入同一个数据库文件。这正是 Quack 协议要解决的问题。
1.2 向量化执行引擎
DuckDB 的高性能来自其列式向量化执行引擎。与传统逐行处理不同,DuckDB 一次处理一批数据(通常是 2048 行),充分利用 CPU 缓存和 SIMD 指令:
传统行式处理: row1 → row2 → row3 → ... (每次处理一行)
DuckDB 向量化: [row1..row2048] → [row2049..row4096] → ... (每次处理一批)
这种设计让 DuckDB 在笔记本电脑上就能处理 TB 级数据,而不需要任何集群基础设施。
二、DuckLake v1.0:用 SQL 重新定义湖仓格式
2.1 湖仓格式的「元数据困境」
在 DuckLake 出现之前,湖仓格式(Lakehouse Format)的主流选择是 Delta Lake 和 Apache Iceberg。它们的核心思路是一致的:把数据以 Parquet 文件的形式存储在对象存储(S3/GCS/Azure Blob)上,然后用一组元数据文件来追踪这些数据文件的版本、schema、分区等信息。
问题在于:这些元数据文件是散布在对象存储中的 JSON/Avro 文件。这意味着:
- 元数据查询需要解析文件:每次查询表的 schema、分区信息,都要从对象存储下载并解析元数据文件
- 并发写入需要锁机制:多个 writer 同时修改元数据文件时,需要复杂的乐观并发控制
- 元数据操作不是 SQL:你不能用
SELECT来查询元数据,不能用DELETE来清理旧版本 - 小文件问题:频繁的小批量写入会产生大量小文件,需要定期 compaction
DuckLake 的核心洞察是:为什么不用数据库来存储元数据?
2.2 DuckLake 的架构革命
DuckLake 的设计哲学可以用一句话概括:把元数据存储从「散布的文件」变成「一张 SQL 表」。
传统湖仓格式(Delta/Iceberg):
┌─────────────────────────────────────┐
│ Object Storage │
│ ┌──────────┐ ┌──────────┐ │
│ │ data.par │ │ data.par │ ... │
│ └──────────┘ └──────────┘ │
│ ┌──────────────────────┐ │
│ │ _delta_log/000.json │ │
│ │ _delta_log/001.json │ ... │
│ └──────────────────────┘ │
└─────────────────────────────────────┘
元数据 = JSON 文件,散布在对象存储中
DuckLake:
┌─────────────────────────────────────┐
│ Object Storage │
│ ┌──────────┐ ┌──────────┐ │
│ │ data.par │ │ data.par │ ... │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────┘
↑ 所有数据文件
┌─────────────────────────────────────┐
│ Catalog Database (SQL) │
│ ┌────────────────────────────┐ │
│ │ ducklake_tables │ │
│ │ ducklake_files │ │
│ │ ducklake_snapshots │ │
│ │ ducklake_data_files │ │
│ └────────────────────────────┘ │
└─────────────────────────────────────┘
元数据 = SQL 表,存储在任何关系型数据库中
关键区别:DuckLake 的元数据存储在一个支持 SQL 的关系型数据库中(可以是 SQLite、PostgreSQL,甚至 DuckDB 自身)。这意味着:
- 元数据操作就是 SQL 操作
- 并发控制由数据库的事务机制保证
- 元数据查询极其高效(数据库索引加速)
- 可以用标准 SQL 工具管理元数据
2.3 Data Inlining:解决小文件问题的杀手级特性
DuckLake 最引人注目的特性是 Data Inlining(数据内联)。传统湖仓格式中,每次 INSERT 都会创建一个新的 Parquet 文件,即使是插入一行数据。这导致了臭名昭著的「小文件问题」。
DuckLake 的解决方案:小批量写入直接存在 Catalog 数据库中,不创建新文件。
-- DuckLake 的 Data Inlining 演示
CREATE TABLE lake.events (
id INT PRIMARY KEY,
event_type VARCHAR,
ts TIMESTAMP
);
-- 插入数据:不会在对象存储中创建新文件!
INSERT INTO lake.events VALUES
(1, 'click', '2026-08-01 10:00:00'),
(2, 'view', '2026-08-01 10:01:00');
-- 删除数据:同样不创建新文件
DELETE FROM lake.events WHERE id = 1;
-- 此时对象存储中没有任何新文件
SELECT * FROM ducklake_list_files('lake', 'events');
-- 返回空结果
-- 手动 CHECKPOINT 才会将内联数据刷新到对象存储
CHECKPOINT;
默认阈值是 10 行——低于此阈值的写入全部在 Catalog 数据库中完成。这彻底解决了小文件问题,同时让流式写入变得可行。
2.4 排序表与桶分区
DuckLake v1.0 还引入了两个提升查询性能的关键特性:
排序表(Sorted Tables):对高基数列(如 ID、时间戳)进行排序,大幅提升范围查询性能:
CREATE TABLE lake.metrics (
metric_id INT,
timestamp TIMESTAMP,
value DOUBLE
);
-- 按时间排序
ALTER TABLE lake.metrics SET SORTED BY (timestamp ASC);
-- 这个查询会自动利用排序信息进行文件级剪枝
SELECT * FROM lake.metrics
WHERE timestamp BETWEEN '2026-08-01' AND '2026-08-02';
桶分区(Bucket Partitioning):对高基数列使用哈希分桶,兼顾分区收益和写入性能:
CREATE TABLE lake.user_events (
user_id BIGINT,
event_type VARCHAR,
payload JSON
);
-- 按 user_id 分 8 个桶
ALTER TABLE lake.user_events
SET PARTITIONED BY (bucket(8, user_id));
-- 查询 user_id = 42 的数据时,只扫描 1/8 的桶
SELECT * FROM lake.user_events WHERE user_id = 42;
2.5 Iceberg 兼容性
DuckLake 并非要取代 Iceberg,而是要与 Iceberg 共存。DuckLake v1.0 在数据层面保持了与 Iceberg 的兼容性:
- 支持 Deletion Vectors(来自 Iceberg v3 规范)
- 支持 Puffin 文件格式存储删除向量
- 可以读取和写入 Iceberg 兼容的 Parquet 文件
这意味着你可以在同一个数据湖中混合使用 DuckLake 和 Iceberg 表,实现渐进式迁移。
三、Quack 协议:DuckDB 的「HTTP 时刻」
3.1 嵌入式架构的「阿喀琉斯之踵」
DuckDB 一直以来引以为傲的嵌入式架构有一个天然限制:多进程无法同时写入同一个数据库文件。这在很多场景下是致命的:
- 多个数据采集进程同时写入同一个 DuckDB 数据库
- 一个进程写入,另一个进程查询驱动 Dashboard
- 微服务架构中多个服务需要共享数据
之前的变通方案包括:使用 Arrow Flight SQL 协议、MotherDuck 的私有协议、甚至切换到 PostgreSQL。DuckDB 团队终于决定:既然这么多人需要,那就自己做一个。
3.2 Quack 的设计哲学:基于 HTTP,简单至上
Quack 协议的设计遵循 DuckDB 的一贯哲学:简单、实用、基于成熟技术。
┌──────────┐ HTTP/HTTPS ┌──────────┐
│ DuckDB │ ←──────────────→ │ DuckDB │
│ Client │ application/ │ Server │
│ │ duckdb 格式 │ │
└──────────┘ └──────────┘
↑ ↑
可以是任意 可以是任意
DuckDB 实例 DuckDB 实例
关键设计决策:
- 基于 HTTP:不需要发明新协议,利用 HTTP 生态系统(负载均衡、防火墙、认证)
- Request-Response 模式:客户端驱动所有交互,简单可预测
- 自定义序列化格式:
application/duckdbMIME 类型,使用 DuckDB 内部的高效序列化原语 - 默认绑定 localhost:安全第一,不建议直接暴露到公网
- 默认端口 9494:致敬 Netscape Navigator 发布的年份(1994)
3.3 快速上手:两个 DuckDB 实例对话
Quack 的使用体验极其简单:
-- DuckDB 实例 #1:启动服务器
CALL quack_serve(
'quack:localhost',
token = 'super_secret'
);
-- 创建一些数据
CREATE TABLE hello AS
FROM VALUES ('world') v(s);
-- DuckDB 实例 #2:连接到远程服务器
CREATE SECRET (
TYPE quack,
TOKEN 'super_secret'
);
ATTACH 'quack:localhost' AS remote;
-- 直接查询远程表!
FROM remote.hello;
-- 输出: world
就像两个鸭子在「quack quack」地对话一样自然。
3.4 性能基准:比 PostgreSQL 协议快多少?
DuckDB 团队在 AWS m8g.2xlarge 实例(8 vCPU, 32 GB RAM, 15 Gbps 网络)上进行了基准测试,对比了 Quack、PostgreSQL 协议和 Arrow Flight SQL:
批量传输性能(传输 TPC-H lineitem 表):
| 行数 | PostgreSQL 协议 | Arrow Flight SQL | Quack |
|---|---|---|---|
| 600万 | ~12s | ~2.1s | ~1.8s |
| 1500万 | ~30s | ~4.8s | ~3.9s |
| 6000万 (76GB) | 超时 | ~18s | ~14s |
小事务性能(单行 INSERT/SELECT):
| 操作 | PostgreSQL 协议 | Quack |
|---|---|---|
| 单行 INSERT | ~2.5ms | ~0.8ms |
| 单行 SELECT | ~1.2ms | ~0.4ms |
| 1000行批量 INSERT | ~45ms | ~12ms |
Quack 在批量传输和小事务两个极端场景下都表现优异。关键优化点:
- 单次往返完成查询:连接建立后,一个查询只需一次 HTTP 请求/响应
- 高效的批量传输:使用 DuckDB 内部的序列化原语,比 PostgreSQL 协议的行格式高效得多
- 并行数据传输:支持多线程并行传输大结果集
3.5 认证与授权:可扩展的安全模型
Quack 的安全模型同样遵循 DuckDB 的可扩展哲学:
-- 默认认证:随机 Token
-- 服务器启动时自动生成,客户端需要提供相同的 Token
-- 自定义认证:你可以用自己的逻辑
-- 例如查询 LDAP、读取配置文件、甚至调用外部 API
CALL quack_serve(
'quack:localhost',
auth_callback => 'my_custom_auth_func'
);
-- 自定义授权:检查每个查询的权限
CALL quack_serve(
'quack:localhost',
authz_callback => 'my_custom_authz_func'
);
认证和授权回调甚至可以是 SQL 宏,极大降低了自定义安全策略的门槛。
3.6 DuckDB-WASM 原生支持
Quack 协议的一个杀手级应用:DuckDB-WASM 可以直接通过 Quack 连接到远程 DuckDB 服务器。
这意味着你可以在浏览器中运行 DuckDB,直接查询远端服务器上的数据,无需任何中间层。这为构建基于 Web 的数据分析应用打开了全新的可能性。
四、异步 I/O 重写:「Work, Thread, Work」的工程哲学
4.1 为什么需要异步 I/O?
DuckDB 的传统 I/O 模型是同步阻塞的:当查询需要读取文件时,执行线程会阻塞等待 I/O 完成。这在本地 SSD 上问题不大,但在以下场景下成为瓶颈:
- 从 S3/GCS 等对象存储读取数据(网络延迟高)
- 查询涉及大量小文件(I/O 密集)
- 并发查询竞争 I/O 资源
4.2 三阶段异步模型
DuckDB 2026 年 7 月发布的异步 I/O 重写采用了「Work, Thread, Work」三阶段模型:
阶段 1: Work(工作线程)
┌─────────────────────────────────┐
│ 查询执行 → 发现需要 I/O → │
│ 创建 I/O 请求 → 提交到队列 → │
│ 继续处理其他查询 │
└─────────────────────────────────┘
↓
阶段 2: Thread(I/O 线程池)
┌─────────────────────────────────┐
│ I/O 线程从队列取请求 → │
│ 执行实际的磁盘/网络读写 → │
│ 完成后将结果放入结果队列 │
└─────────────────────────────────┘
↓
阶段 3: Work(工作线程)
┌─────────────────────────────────┐
│ 查询执行 → 检查结果队列 → │
│ 获取 I/O 结果 → 继续执行 │
└─────────────────────────────────┘
关键设计:
- 工作线程不阻塞:发现 I/O 需求后,立即释放工作线程去处理其他任务
- 专用 I/O 线程池:独立的线程池处理所有 I/O 操作,不与计算线程竞争
- 批量 I/O 调度:I/O 线程可以批量处理多个请求,减少系统调用开销
- 零拷贝数据传递:I/O 结果直接传递给工作线程,无需额外复制
4.3 性能提升
异步 I/O 重写带来的性能提升是显著的:
| 场景 | 同步 I/O | 异步 I/O | 提升 |
|---|---|---|---|
| S3 Parquet 读取 (1GB) | 8.2s | 2.1s | 3.9x |
| 本地 SSD 多文件查询 | 1.2s | 0.6s | 2.0x |
| 并发查询 (8线程) | 4.8s | 1.3s | 3.7x |
| 流式 ETL 管道 | 120 rows/s | 450 rows/s | 3.8x |
对于从 S3 读取 Parquet 文件的场景,提升最为显著(接近 4 倍),这是因为异步 I/O 允许 DuckDB 在等待网络响应的同时处理其他查询的计算任务。
五、三位一体:DuckDB + DuckLake + Quack 的架构全景
这三个组件不是孤立存在的,它们共同构成了一个完整的数据基础设施平台:
┌─────────────────────────────────────────────────────┐
│ 应用层 │
│ Python notebooks / BI 工具 / Web 应用 / ETL 管道 │
└──────────────────┬──────────────────────────────────┘
│ Quack 协议 (HTTP)
┌──────────────────▼──────────────────────────────────┐
│ DuckDB 计算引擎 │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 向量化执行 │ │ 异步 I/O │ │ SQL 解析器 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
└──────────────────┬──────────────────────────────────┘
│
┌──────────────────▼──────────────────────────────────┐
│ 数据层 │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ DuckLake │ │ Parquet │ │ CSV/JSON │ │
│ │ (SQL 元数据)│ │ 文件 │ │ 文件 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ Catalog DB (SQLite / PostgreSQL / DuckDB) │ │
│ └────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
典型使用场景:
- 数据科学工作流:Python notebook 直接用 DuckDB 查询 DuckLake 中的数据,无需集群
- 实时数据管道:多个数据采集进程通过 Quack 协议写入同一个 DuckDB 服务器,DuckLake 管理版本
- Web 分析应用:DuckDB-WASM 通过 Quack 连接后端 DuckDB 服务器,浏览器直接查询
- 混合云架构:本地 DuckDB 通过 Quack 连接云端 DuckDB,DuckLake 元数据存在 PostgreSQL
六、实战:从零搭建 DuckDB 湖仓平台
6.1 环境准备
# 安装 DuckDB CLI(macOS)
brew install duckdb
# 或者直接下载二进制
curl -fsSL https://install.duckdb.org | sh
6.2 创建 DuckLake 表
-- 加载 ducklake 扩展
INSTALL ducklake;
LOAD ducklake;
-- 创建一个 DuckLake,使用 SQLite 作为 Catalog
-- (生产环境建议使用 PostgreSQL)
ATTACH 'ducklake:metadata.db' AS lake
(DATA_PATH 's3://my-bucket/my-lake/');
-- 创建表
CREATE TABLE lake.sales (
sale_id INT PRIMARY KEY,
product_id INT,
quantity INT,
price DOUBLE,
sale_date TIMESTAMP
);
-- 插入数据(小批量会自动内联到 Catalog)
INSERT INTO lake.sales VALUES
(1, 101, 5, 29.99, '2026-08-01 10:00:00'),
(2, 102, 3, 49.99, '2026-08-01 11:00:00'),
(3, 101, 2, 29.99, '2026-08-01 12:00:00');
-- 查询数据(和普通 DuckDB 表一样!)
SELECT product_id, SUM(quantity * price) as total_revenue
FROM lake.sales
GROUP BY product_id
ORDER BY total_revenue DESC;
6.3 设置 Quack 服务器
-- 启动 DuckDB 服务器
CALL quack_serve(
'quack:0.0.0.0',
port => 9494,
token => 'my-secret-token'
);
6.4 客户端连接
-- 另一个 DuckDB 实例连接
CREATE SECRET (
TYPE quack,
TOKEN 'my-secret-token'
);
ATTACH 'quack:my-server:9494' AS remote;
-- 远程查询
SELECT * FROM remote.lake.sales
WHERE sale_date > '2026-08-01';
-- 本地写入,远程读取
CREATE TABLE remote.lake.new_data AS
FROM local_table;
6.5 Python 集成
import duckdb
# 连接到 DuckLake
conn = duckdb.connect()
conn.execute("INSTALL ducklake; LOAD ducklake")
conn.execute("""
ATTACH 'ducklake:metadata.db' AS lake
(DATA_PATH 's3://my-bucket/my-lake/')
""")
# 查询数据
df = conn.execute("""
SELECT product_id,
SUM(quantity) as total_qty,
SUM(quantity * price) as revenue
FROM lake.sales
WHERE sale_date >= '2026-08-01'
GROUP BY product_id
""").df()
print(df)
# 通过 Quack 连接远程服务器
conn.execute("CREATE SECRET (TYPE quack, TOKEN 'my-secret-token')")
conn.execute("ATTACH 'quack:my-server:9494' AS remote")
# 远程查询
remote_df = conn.execute("SELECT * FROM remote.lake.sales").df()
七、性能优化实战
7.1 利用排序提升查询性能
-- 对时间戳列排序,范围查询性能提升 5-10 倍
ALTER TABLE lake.events SET SORTED BY (event_time ASC);
-- 这个查询会自动利用排序信息跳过不相关的文件
SELECT * FROM lake.events
WHERE event_time BETWEEN '2026-08-01' AND '2026-08-02';
7.2 桶分区优化高基数查询
-- 对 user_id 分桶,等值查询只扫描 1/N 的数据
ALTER TABLE lake.user_actions
SET PARTITIONED BY (bucket(16, user_id));
-- 这个查询只扫描 1/16 的桶
SELECT * FROM lake.user_actions WHERE user_id = 12345;
7.3 Data Inlining 调优
-- 调整内联阈值(默认 10 行)
CALL lake.set_option('data_inlining_row_limit', 50);
-- 对特定表禁用内联(如果你需要即时可见性)
CALL lake.set_option('data_inlining_row_limit', 0, table_name => 'real_time_metrics');
7.4 Quack 协议优化
-- 使用 query() 函数减少数据传输
-- 不要:SELECT * FROM remote.big_table (会传输全部数据)
-- 要:在远程执行聚合
FROM remote.query('
SELECT category, SUM(amount) as total
FROM big_table
GROUP BY category
');
-- 使用并行传输
-- Quack 自动检测大结果集并使用多线程传输
八、DuckDB 生态的未来展望
8.1 DuckLake v1.1 和 v2.0 路线图
DuckDB 团队已经公布了 DuckLake 的未来规划:
v1.1(即将发布):
- Variant 类型内联支持
- 多删除向量 Puffin 文件
- 更好的 Iceberg 兼容性
v2.0(中长期):
- Git 式分支:为数据创建分支,支持合并操作——「数据的 Git」
- 基于角色的权限控制:直接在 DuckLake 层面管理访问权限
- 增量物化视图:只刷新变化部分的物化视图
8.2 Quack 协议的演进
Quack 协议的未来方向可能包括:
- 更丰富的认证机制(OAuth、mTLS)
- 流式查询支持(Server-Sent Events)
- 跨 DuckDB 实例的分布式查询优化
8.3 DuckDB 在 AI 时代的位置
随着 AI Agent 和 LLM 应用的爆发,DuckDB 的嵌入式特性使其成为 AI 应用的理想数据层:
- 本地向量存储:配合 pgvector 扩展,DuckDB 可以作为本地向量数据库
- AI Agent 的数据工具:通过 MCP 协议集成,AI Agent 可以直接查询 DuckDB
- 端侧推理数据预处理:在边缘设备上用 DuckDB 处理数据,再送入本地 LLM
九、与竞品对比
| 特性 | DuckDB + DuckLake | Delta Lake | Apache Iceberg | SQLite |
|---|---|---|---|---|
| 元数据存储 | SQL 数据库 | JSON 文件 | Avro 文件 | 无 |
| 嵌入式支持 | 原生 | 需要 Spark | 需要引擎 | 原生 |
| OLAP 性能 | 极强 | 依赖引擎 | 依赖引擎 | 弱 |
| 小文件处理 | Data Inlining | Compaction | Compaction | N/A |
| 多写支持 | Quack 协议 | 需要协调 | 需要协调 | 不支持 |
| 查询语言 | 标准 SQL | Spark SQL | Spark SQL | SQL |
| 学习曲线 | 低 | 中 | 高 | 极低 |
十、总结
DuckDB 在 2026 年的三大更新——DuckLake v1.0、Quack 协议、异步 I/O——标志着它从一个「好用的本地分析工具」进化为一个完整的数据基础设施平台。
DuckLake 用 SQL 重新定义了湖仓格式,解决了传统湖仓格式的元数据困境和小文件问题。Quack 协议让多个 DuckDB 实例可以协作,终结了嵌入式数据库无法多写的历史。异步 I/O 则让 DuckDB 在云端和高并发场景下的性能提升了一个数量级。
对于数据工程师来说,DuckDB 生态意味着:
- 更简单的架构:不需要 Spark 集群就能构建湖仓
- 更低的成本:嵌入式架构消除了服务器成本
- 更好的体验:标准 SQL、零配置、直接查询文件
- 更广的应用场景:从笔记本到边缘设备到云端,DuckDB 无处不在
数据基础设施的未来,可能不是更大的集群,而是更智能的嵌入式引擎。DuckDB 正在证明这一点。
参考资源:
- DuckDB 官方文档:https://duckdb.org/docs
- DuckLake 规范:https://ducklake.select/docs/stable/specification/introduction
- Quack 协议文档:https://duckdb.org/docs/current/quack/overview.html
- DuckDB GitHub:https://github.com/duckdb/duckdb
- DuckLake GitHub:https://github.com/duckdb/ducklake