市面上有许多数据库管理系统(DBMS)。但没有一种通用的数据库系统。所有系统都通过不同的权衡来更好地适应特定用例。DuckDB也不例外。在这里,我们尝试解释DuckDB的目标以及我们如何通过技术手段实现这些目标。首先,DuckDB是一个关系型(面向表格的)DBMS,支持结构化查询语言(SQL)。
简单
SQLite是全球部署最广泛的DBMS。安装简单以及嵌入式进程内运行是其成功的核心。DuckDB采纳了这些简单性和嵌入式运行的理念。
DuckDB没有外部依赖,无论是编译时还是运行时。对于发布版本,DuckDB的整个源代码树被编译成两个文件,一个头文件和一个实现文件,即所谓的“集成文件”。这极大地简化了部署和与其他构建过程的集成。对于构建,构建DuckDB仅需要一个可用的C++11编译器。
对于DuckDB,无需安装、更新和维护DBMS服务器软件。DuckDB不作为单独的进程运行,而是完全嵌入宿主进程中。对于DuckDB所针对的分析用例,这还有额外的高速数据传输到和从数据库的优势。在某些情况下,DuckDB可以在不复制数据的情况下处理外部数据。例如,DuckDB Python包可以直接在Pandas数据上运行查询,而无需导入或复制任何数据。
便携
得益于没有依赖,DuckDB极具便携性。它可以编译到所有主要操作系统(Linux、macOS、Windows)和CPU架构(x86、ARM)上。它可以部署从小型、资源受限的边缘设备到拥有100+CPU核心的大型多TB内存服务器。通过DuckDB-Wasm,DuckDB还可以在网页浏览器甚至手机上运行。
DuckDB提供了Java、C、C++、Go、Node.js等其他语言的API。
功能丰富
DuckDB提供了强大的数据管理功能。它广泛支持SQL中的复杂查询,拥有庞大的函数库、窗口函数等。DuckDB通过我们定制的、针对批量优化的多版本并发控制(MVCC)提供事务保证(ACID属性)。数据可以存储在持久的单文件数据库中。DuckDB支持二级索引来加速试图找到单个表条目的查询。
DuckDB深度集成到Python和R中,用于高效的交互式数据分析。
快速
DuckDB旨在支持分析查询工作负载,也称为在线分析处理(OLAP)。这些工作负载的特点是复杂、运行时间相对较长的查询,处理存储数据集的相当一部分,例如对整个表的聚合或多个大表之间的连接。对数据的更改也预期是相当大规模的,一次性追加多行,或同时更改或添加表的大部分。
为了高效支持这种工作负载,至关重要的是减少每个单独值所消耗的CPU周期数。在数据管理中实现这一目标的最新技术是向量化或即时查询执行引擎。DuckDB使用列式向量化查询执行引擎,查询仍然是解释型的,但是一大批值(一个“向量”)在一次操作中被处理。这极大地减少了传统系统如PostgreSQL、MySQL或SQLite中存在的开销,这些系统是逐行顺序处理数据的。向量化查询执行在OLAP查询中带来了更好的性能。
可扩展
DuckDB提供了一种灵活的扩展机制,允许定义新的数据类型、函数、文件格式和新的SQL语法。事实上,DuckDB的许多关键功能,如对Parquet文件格式、JSON、时区以及HTTP(S)和S3协议的支持,都是作为扩展实现的。扩展也可以在DuckDB Wasm中使用。
免费
DuckDB的开发始于主要开发者在荷兰担任公职人员时。我们认为,将我们的工作成果免费提供给荷兰或任何其他地方的任何人,是我们的责任和对社会的义务。这就是为什么DuckDB在非常宽松的MIT许可证下发布。DuckDB是开源的,整个源代码在GitHub上免费提供。我们欢迎任何遵守我们行为准则的人做出贡献。
严格测试
虽然DuckDB最初是由一个研究小组创建的,但它从未打算成为一个研究原型。相反,它旨在成为一个稳定和成熟的数据库系统。为了实现这种稳定性,DuckDB使用持续集成进行了密集测试。DuckDB的测试套件目前包含数百万个查询,包括从SQLite、PostgreSQL和MonetDB的测试套件中改编的查询。测试在各种平台和编译器上重复进行。每个拉取请求都会针对完整的测试设置进行检查,只有通过后才会合并。
除了这个测试套件,我们还运行各种测试,以在重负载下对DuckDB进行压力测试。我们运行TPC-H和TPC-DS基准测试,并运行各种测试,其中DuckDB被多个客户端并行使用。
同行评审的论文和论文工作
• Runtime-Extensible Parsers(CIDR 2025)
• Robust External Hash Aggregation in the Solid State Age(ICDE 2024)
• These Rows Are Made for Sorting and That’s Just What We’ll Do(ICDE 2023)
• Join Order Optimization with(Almost)No Statistics(Master thesis,2022)
• DuckDB-Wasm:Fast Analytical Processing for the Web(VLDB 2022 Demo)
• Data Management for Data Science-Towards Embedded Analytics(CIDR 2020)
• DuckDB:an Embeddable Analytical Database(SIGMOD 2019 Demo)
其他项目
要了解使用DuckDB的项目,请访问Awesome DuckDB仓库。
站在巨人的肩膀上
DuckDB使用了来自各种开源项目的一些组件,并从科学出版物中汲取灵感。我们对此非常感激。以下是概述:
• 执行引擎:向量化执行引擎受到Peter Boncz、Marcin Zukowski和Niels Nes撰写的论文MonetDB/X100:Hyper-Pipelining Query Execution的启发。MonetDB/X100后来成为了Vectorwise(Actian Vector)数据库系统。
• 优化器:DuckDB的优化器从Guido Moerkotte和Thomas Neumann撰写的论文Dynamic programming strikes back以及Thomas Neumann和Alfons Kemper撰写的论文Unnesting Arbitrary Queries中汲取灵感。
• 并发控制:我们的MVCC实现受到Thomas Neumann、Tobias Mühlbauer和Alfons Kemper撰写的论文Fast Serializable Multi-Version Concurrency Control for Main-Memory Database Systems的启发。
• 二级索引:DuckDB基于Viktor Leis、Alfons Kemper和Thomas Neumann撰写的论文The Adaptive Radix Tree:ARTful Indexing for Main-Memory Databases支持二级索引。
• SQL窗口函数:DuckDB的窗口函数实现使用了Viktor Leis、Kan Kundhikanjana、Alfons Kemper和Thomas Neumann撰写的论文Efficient Processing of Window Functions in Analytical SQL Queries中描述的Segment Tree Aggregation。
• SQL不等式连接:DuckDB的不等式连接实现使用了Zuhair Khayyat、William Lucia、Meghna Singh、Mourad Ouzzani、Paolo Papotti、Jorge-Arnulfo Quiané-Ruiz、Nan Tang和Panos Kalnis撰写的论文Lightning Fast and Space Efficient Inequality Joins中描述的IEJoin算法。
• 浮点值压缩:DuckDB支持多种压缩浮点值的算法:
-
Panagiotis Liakos、Katia Papakonstantinopoulou和Yannis Kotidi开发的Chimp
-
Patas,我们内部开发的,以及
-
Azim Afroozeh、Leonard Kuffo和Peter Boncz开发的ALP(自适应无损浮点压缩),他们也贡献了其实现。
• SQL解析器:我们使用了被重新打包为独立库的PostgreSQL解析器。将解析结果转换为我们自己的解析树受到Peloton的启发。
• 外壳:我们使用SQLite外壳来与DuckDB一起工作。
• 正则表达式:DuckDB使用Google的RE2正则表达式引擎。
• 字符串格式化:DuckDB使用fmt字符串格式化库。
• UTF处理:DuckDB使用utf8proc库来检查和规范化UTF8。
• 排序和时间:DuckDB使用ICU库来进行排序、时区和日历支持。
• 测试框架:DuckDB使用Catch2单元测试框架。
• 测试用例:我们使用SQLite的SQL逻辑测试来测试DuckDB。
• 结果验证:Manuel Rigger使用他出色的SQLancer工具来验证DuckDB结果的正确性。
• 查询模糊测试:我们通过sqlsmith
扩展使用SQLsmith来生成随机查询,以进行额外的测试。
• JSON解析器:我们使用yyjson,这是一个用ANSI C编写的高性能JSON库,用于解析DuckDB的JSON扩展中的JSON。