找回密码
 立即注册
首页 业界区 安全 [OLAP] DuckDB : 开源免费的、面向嵌入式场景、列式存储 ...

[OLAP] DuckDB : 开源免费的、面向嵌入式场景、列式存储的分析型数据库

左优扬 3 天前
0 序


  • DuckDB 是近期非常火的一款 AP 数据库,其独特的定位很有趣。甚至有数据库产品考虑将其纳入进来,作为分析能力的扩展。
考虑到项目中一个数据处理场景,就此调研一二。


  • DuckDB 的爆火,也给所有盲目追逐“大数据”的技术人敲响了警钟:


  • DuckDB 是一场复古的叛逆,也是一场属于单机的复仇。它告诉我们:在算力爆炸的今天,小,即是快;简,即是强。
  • 我们被云厂商和大数据鼓吹者洗脑太久了,总觉得不搞个集群、不弄个微服务,架构就不够“高大上”。但技术的本质是解决问题,而不是制造复杂度。


  • 重要结论:


  • DuckDB := 数据分析领域的 SQLLite (列式存储)
适合分析 / 列压缩 / 每一列在磁盘和内存中以分块数组的形式存储
内存局部性优化 / 读取查询速度更快


  • 适用于:单机/嵌入式场景
物联网/移动端/个人PC端/中小企业(TB级以下数据场景,尤其是数百GB级以下)
1 概述:DuckDB

DuckDB 介绍

产品定位与产生背景


  • DuckDB 是一个诞生于2018年,开源免费的、面向嵌入式场景的、列式存储的、In-Process 的 OLAP 数据库。


  • 产生背景:2019 年, SIGMOD 有一篇 Demo 论文介绍 DuckDB:an embedded analytical database。随着单机内存的变大,大部分 OLTP 数据库都能在内存中放得下,而很多 OLAP 也有在单机就能搞定的趋势。单台服务器的内存很容易达到 TB,加上 SSD,搞个几十甚至上百 TB 很容易。DuckDB 就是为了填补这个空白而生的。
  • 定位:一款单机版/嵌入式分析型数据库 (数据分析领域的 SQLLite,但其底层是列式存储
  • Slogan : DuckDB 是一个分析式的 SQL 数据库管理系统
  • https://github.com/duckdb/duckdb


  • 主要编程语言: C/C++
1.png


  • 支持多种数据格式的导入与导出:


  • csv / excel / json / parquet 等本地文件格式
  • http(s) / s3 等远程文件格式
开源情况


  • DuckDB 采用 较为宽松的 MIT 协议开源。
其作为荷兰 CWI 数据库组的一个项目,学术气息比较浓厚,项目的组织很有教科书的感觉,架构很清晰,所以非常适合阅读学习。
从 OSS Insight 拉个一个 Star 数对比,可以看到 DuckDB 发展非常迅速。
https://ossinsight.io/analyze/duckdb/duckdb#overview
2.png

DuckDB 主要特点


  • DuckDB是一个免费的、开源的、面向单机的(嵌入式/非分布式的)数据库管理系统,专为【数据分析】和【在线分析处理】而设计。
这意味着以下几点:


  • 它是免费的开源软件,因此任何人都可以使用和修改代码。
  • 它是面向单机的/嵌入式的。
这意味着DBMS(数据库管理系统)与使用它的应用程序在同一进程中运行。这使得它快速且易于使用。


  • 它针对【数据分析】和【OLAP】(在线分析处理)进行了优化,而不仅仅是像典型数据库那样只针对事务数据。
这意味着数据【按列】而不是【按行】组织以优化聚合和分析。


  • 它支持【标准SQL】,因此可以在数据上运行查询、聚合、连接和其他SQL函数。
  • 它在【进程中运行】,即在应用程序本身内运行,而不是作为单独的进程运行。这消除了进程间通信的开销。
与SQLite一样,它是一个简单的基于文件的数据库。因此,不需要单独安装服务器。只需将库包含在应用程序中即可。
主要优点


  • 易于安装、部署和使用。没有需要配置的服务器,可在应用程序内部嵌入运行,这使得它易于集成到不同编程语言环境中。
  • 尽管它很简单,但DuckDB具有丰富的功能集。它支持完整的SQL标准、事务、二级索引,并且与流行的数据分析编程语言如 Python 和 R 集成良好。
  • 免费的,任何人都可以使用和修改它,这降低了开发人员和数据分析师采用它的门槛。
  • 兼容性很好,几乎无依赖性,甚至可在浏览器中运行。
  • 具有灵活的扩展机制,这对于直接从 CSV、JSON、Parquet、MySQL 或直接从 S3 读取数据特别重要,能够大大提高开发人员的体验。
  • 可提供数据超出内存限制但小于磁盘容量规模下的工作负载,这样分析工作可通过 "便宜"的硬件来完成。
2 安装部署篇


  • DuckDB 安装部署过程相当简单,且支持多种部署模式:
3.png

CLI / Python / Go / Java / Nodejs / C/C++ / R / Rust / ODBC
简言之,DuckDB 提供了非常简单的安装方法,可从官网 https://duckdb.org/install/ 直接下载安装解压即可使用。此外,DuckDB 还可以内置在多种开发语言中使用。
安装 CLI by Windows(Powershell)

DuckDB 可以通过 PSDuckDB 模块与 PowerShell 无缝集成,从而实现从 PowerShell 环境中高效执行分析性 SQL 查询。


  • 以管理员权限打开 PowerShell :
  1. PS C:\Windows\system32> Install-Module PSDuckDB                                                                                                                                                                                                                                                                                                         需要使用 NuGet 提供程序来继续操作
  2. PowerShellGet 需要使用 NuGet 提供程序“2.8.5.201”或更高版本来与基于 NuGet 的存储库交互。必须在“C:\Program
  3. Files\PackageManagement\ProviderAssemblies”或“C:\Users\EDY\AppData\Local\PackageManagement\ProviderAssemblies”中提供 NuGet 提供程序。也可以通过运行
  4. 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force' 安装 NuGet 提供程序。是否要让 PowerShellGet 立即安装并导入 NuGet 提供程序?
  5. [Y] 是(Y)  [N] 否(N)  [S] 暂停(S)  [?] 帮助 (默认值为“Y”): Y
  6. 不受信任的存储库
  7. 你正在从不受信任的存储库安装模块。如果你信任该存储库,请通过运行 Set-PSRepository cmdlet 更改其 InstallationPolicy 值。是否确实要从“PSGallery”安装模块?
  8. [Y] 是(Y)  [A] 全是(A)  [N] 否(N)  [L] 全否(L)  [S] 暂停(S)  [?] 帮助 (默认值为“N”): Y
  9. PS C:\Windows\system32>
复制代码

  • 安装完成后,输入 psduckdb 即可使用
  1. PS C:\Windows\system32> psduckdb
  2. Welcome to PSDuckDB! 01/02/2026 09:02:51
  3. Connected to an in-memory database
  4. PSDuckDB: show databases;
  5. database_name
  6. -------------
  7. memory
  8. PSDuckDB: show tables
  9. PSDuckDB: select 1 as tmp_a
  10. tmp_a
  11. -----
  12.     1
  13. PSDuckDB:
  14. PSDuckDB: exit
  15. PS C:\Windows\system32>
复制代码
安装 CLI by Windows(解压即安装)


  • 下载后解压 zip 安装包,双击打开 duckdb.exe 即可使用
https://duckdb.org/install/?platform=windows&environment=cli

  • duckdb_cli-windows-amd64.zip
  • duckdb_cli-windows-arm64.zip
D:\Program\DuckDB-CLI\duckdb.exe
4.png

3 工作原理与架构篇

数据库架构

5.png


  • DuckDB 数据库可分为多个组件:Parser、Logical Planner、Optimizer、Physical Planner、Execution Engine、Transaction and Storage Managers
Parser


  • DuckDB SQL Parser 源自 Postgres SQL Parser。
Logical Planner


  • 其包含了两个过程 binder、plan generator。前者是解析所有引用的 schema 中的对象(如 table 或 view)的表达式,将其与列名和类型匹配。后者将 binder 生成的 AST 转换为由基本 logical query 查询运算符组成的树,就得到了一颗 type-resolved logical query plan。
Optimizer

优化器部分,会采用多种优化手段对 logical query plan 进行优化,最终生成 physical plan。例如,其内置一组 rewrite rules 来简化 expression tree,例如执行公共子表达式消除和常量折叠。针对表关联,会使用动态规划进行 join order 的优化,针对复杂的 join graph 会 fallback 到贪心算法会消除所有的 subquery。
Execution Engine

DuckDB 最开始采用了基于 Pull-based 的 Vector Volcano 的执行引擎,后来切换到了 Push-based 的 pipelines 执行方法。DuckDB 采用了向量化计算来来加速计算,具有内部实现的多种类型的 vector 以及向量化的 operator。另外出于可移植性原因,没有采用 JIT,因为 JIT引擎依赖于大型编译器库(例如LLVM),具有额外的传递依赖。
Transactions

DuckDB 通过 MVCC 提供了 ACID 的特性,实现了HyPer专门针对混合OLAP OLTP系统定制的可串行化MVCC 变种 。该变种立即 in-place 更新数据,并将先前状态存储在单独的 undo buffer 中,以供并发事务和 abort 使用。
Persistent Storage

DuckDB 使用面向读取优化的 DataBlocks 存储布局(单个文件)。逻辑表被水平分区为 chunks of columns,并使用轻量级压缩方法压缩成 physical block 。每个块都带有每列的min/max 索引,以便快速确定它们是否与查询相关。此外,每个块还带有每列的轻量级索引,可以进一步限制扫描的值数量。
4 使用指南篇

(本地)数据导入和导出


  • 推荐文献


  • 数据导入概述 - DuckDB 【推荐】


  • 支持的数据导入与导出场景


  • CSV 导入
  1. SELECT * FROM read_csv('input.csv');
复制代码


  • CSV 导出
  1. COPY tbl TO 'output.csv' (HEADER, DELIMITER ',');
复制代码


  • 直接读取文件
  1. SELECT
  2.     size, parse_path(filename), content
  3. FROM read_text('test/sql/table_function/files/*.txt');
复制代码


  • Excel 导入
  1. SELECT * FROM read_xlsx('test_excel.xlsx');
复制代码


  • Excel 导出
  1. COPY tbl TO 'output.xlsx' WITH (FORMAT xlsx);
复制代码


  • JSON 导入
  1. SELECT * FROM read_json_auto('input.json');
复制代码


  • JSON 导出
  1. # COPY (SELECT * FROM range(3) tbl(n)) TO 'output.json';
  2. {"n":0}
  3. {"n":1}
  4. {"n":2}
  5. # COPY (SELECT * FROM range(3) tbl(n)) TO 'output.json' (ARRAY);
  6. [
  7.         {"n":0},
  8.         {"n":1},
  9.         {"n":2}
  10. ]
复制代码


  • Parquet 导入
https://duckdb.org/docs/stable/guides/network_cloud_storage/http_import
  1. SELECT * FROM read_parquet('input.parquet');
  2. SELECT * FROM read_parquet('https://domain/path/to/file.parquet');
  3. SELECT * FROM read_parquet('s3://{bucketName}/path/to/file.parquet');
复制代码


  • Parquet 导出
  1. COPY (SELECT * FROM tbl) TO 'output.parquet' (FORMAT parquet);
复制代码


  • 查询Parquet文件
  1. SELECT * FROM read_parquet('input.parquet');
复制代码


  • 文件访问:协议
DuckDB 支持使用该协议。目前支持以下格式:file:


  • file:/some/path(host完全省略)
  • file:///some/path(空主)
  • file://localhost/some/path (localhost作为host)
请注意,以下格式不被支持,因为它们是非标准的:

  • file:some/relative/path(相对路径)
  • file://some/path(双斩路径)
    此外,该协议目前不支持远程(非本地主机)主机。
Parquet 专章


  • 查看 parquet 文件的数据
  1. D select * from read_parquet("D:\Program-Data\DuckDB\datasources\tb_demo.parquet") limit 10
  2. col_0|col_1|col_2|col_3|
  3. -----+-----+-----+-----+
  4.     1|    2|    3|    4|
  5.     5|    6|    7|    8|
  6.     9|   10|   11|   12|
  7.    13|   14|   15|   16|
复制代码


  • 查询多个parquet文件的数据 (当数据结构(定义)一致时, 支持多个文件读.)
  1. -- read 3 parquet files and treat them as a single table   
  2. SELECT * FROM read_parquet(['file1.parquet', 'file2.parquet', 'file3.parquet']);
复制代码
WildcardDescription*matches any number of any characters (including none)?matches any single character[abc]matches one character given in the bracket[a-z]matches one character from the range given in the bracket
  1. -- read all files that match the glob pattern   
  2. SELECT * FROM read_parquet('test/*.parquet');   
  3. -- Read all parquet files from 2 specific folders   
  4. SELECT * FROM read_parquet(['folder1/*.parquet','folder2/*.parquet']);
复制代码

  • 查看 parquet 文件的元数据
文件路径 / 列名 / 列序 / 列类型 / 压缩算法(zstd / snappy / ...) / ...
  1. D SELECT * FROM parquet_metadata("D:\Program-Data\DuckDB\datasources\tb_demo.parquet")
  2. file_name                                         |row_group_id|row_group_num_rows|row_group_num_columns|row_group_bytes|column_id|file_offset|num_values|path_in_schema|type |stats_min|stats_max|stats_null_count|stats_distinct_count|stats_min_value|stats_max_value|compression|encodings                 |index_page_offset|dictionary_page_offset|data_page_offset|total_compressed_size|total_uncompressed_size|key_value_metadata|bloom_filter_offset|bloom_filter_length|min_is_exact|max_is_exact|row_group_compressed_bytes|geo_bbox|geo_types|
  3. --------------------------------------------------+------------+------------------+---------------------+---------------+---------+-----------+----------+--------------+-----+---------+---------+----------------+--------------------+---------------+---------------+-----------+--------------------------+-----------------+----------------------+----------------+---------------------+-----------------------+------------------+-------------------+-------------------+------------+------------+--------------------------+--------+---------+
  4. D:\Program-Data\DuckDB\datasources\tb_demo.parquet|           0|                 4|                    4|            476|        0|          0|         4|col_0         |INT64|1        |13       |               0|                    |1              |13             |SNAPPY     |PLAIN, RLE, RLE_DICTIONARY|                 |                     4|              46|                  117|                    119|{}                |                   |                   |true        |true        |                         1|        |NULL     |
  5. D:\Program-Data\DuckDB\datasources\tb_demo.parquet|           0|                 4|                    4|            476|        1|          0|         4|col_1         |INT64|2        |14       |               0|                    |2              |14             |SNAPPY     |PLAIN, RLE, RLE_DICTIONARY|                 |                   121|             163|                  117|                    119|{}                |                   |                   |true        |true        |                         1|        |NULL     |
  6. D:\Program-Data\DuckDB\datasources\tb_demo.parquet|           0|                 4|                    4|            476|        2|          0|         4|col_2         |INT64|3        |15       |               0|                    |3              |15             |SNAPPY     |PLAIN, RLE, RLE_DICTIONARY|                 |                   238|             280|                  117|                    119|{}                |                   |                   |true        |true        |                         1|        |NULL     |
  7. D:\Program-Data\DuckDB\datasources\tb_demo.parquet|           0|                 4|                    4|            476|        3|          0|         4|col_3         |INT64|4        |16       |               0|                    |4              |16             |SNAPPY     |PLAIN, RLE, RLE_DICTIONARY|                 |                   355|             397|                  117|                    119|{}                |                   |                   |true        |true        |                         1|        |NULL     |
复制代码

  • 查询 parquet 文件的数据结构(定义)
  1. -- fetch the column names and column types   
  2. D DESCRIBE SELECT * FROM "D:\Program-Data\DuckDB\datasources\tb_demo.parquet";   
  3. column_name|column_type|null|key|default|extra|
  4. -----------+-----------+----+---+-------+-----+
  5. col_0      |BIGINT     |YES |   |       |     |
  6. col_1      |BIGINT     |YES |   |       |     |
  7. col_2      |BIGINT     |YES |   |       |     |
  8. col_3      |BIGINT     |YES |   |       |     |
  9. -- fetch the internal schema of a parquet file   
  10. D SELECT * FROM parquet_schema("D:\Program-Data\DuckDB\datasources\tb_demo.parquet");   
  11. file_name                                         |name  |type |type_length|repetition_type|num_children|converted_type|scale|precision|field_id|logical_type|duckdb_type|
  12. --------------------------------------------------+------+-----+-----------+---------------+------------+--------------+-----+---------+--------+------------+-----------+
  13. D:\Program-Data\DuckDB\datasources\tb_demo.parquet|schema|     |           |REQUIRED       |           4|              |     |         |        |            |           |
  14. D:\Program-Data\DuckDB\datasources\tb_demo.parquet|col_0 |INT64|           |OPTIONAL       |            |              |     |         |        |            |BIGINT     |
  15. D:\Program-Data\DuckDB\datasources\tb_demo.parquet|col_1 |INT64|           |OPTIONAL       |            |              |     |         |        |            |BIGINT     |
  16. D:\Program-Data\DuckDB\datasources\tb_demo.parquet|col_2 |INT64|           |OPTIONAL       |            |              |     |         |        |            |BIGINT     |
  17. D:\Program-Data\DuckDB\datasources\tb_demo.parquet|col_3 |INT64|           |OPTIONAL       |            |              |     |         |        |            |BIGINT     |
复制代码

  • 将 parquet 文件的数据插入本地表
  1. -- insert the data from the parquet file in the table   
  2. INSERT INTO people SELECT * FROM read_parquet('test.parquet');   
  3.    
  4. -- create a table directly from a parquet file   
  5. CREATE TABLE people AS SELECT * FROM read_parquet('test.parquet');   
  6.   
  7. -- or  
  8. COPY tbl FROM 'input.parquet' (FORMAT PARQUET);
复制代码

  • 创建parquet文件视图
  1. -- create a view over the parquet file   
  2. CREATE VIEW people AS SELECT * FROM read_parquet('test.parquet');   
  3.    
  4. -- query the parquet file   
  5. SELECT * FROM people;
复制代码
(远程)网络与云存储

S3 Parquet Import


  • 推荐文献


  • S3 Parquet 导入 - DuckDB


  • 前提条件


  • 要从 S3 加载 Parquet 文件,需要 httpfs 扩展名。这可以通过SQL命令安装。这个程序只需要运行一次 INSTALL 命令:
  1. INSTALL httpfs;
复制代码
6.png



  • 要加载扩展以供使用,请使用SQL命令:
  1. LOAD httpfs;
复制代码
7.png


  • 凭据与配置
加载扩展后,设置凭证和S3区域读取数据:httpfs
  1. -- 创建 SECRET
  2. CREATE OR REPLACE SECRET s3_secret_qiniu ( -- or 持久化存储密钥: CREATE PERSISTENT SECRET s3_secret_qiniu (
  3.     TYPE s3
  4.     -- , PROVIDER config -- (可选配置项) 作用: 当遇到 s3: 协议的 http 文件时,默认使用此 secret
  5.     , ENDPOINT 's3.cn-south-1.qiniucs.com' -- 's3.oss-cn-beijing.aliyuncs.com' (阿里云为例)
  6.     , KEY_ID 'R534353545DrQp0ipYngKsey' -- 'AKIAIO3535355AMPLE'
  7.     , SECRET '02xSD945454545gl4543535sD' -- 'wJalrXUtnF353535DENG/bPxRfiCYEXAMPLEKEY'
  8.    
  9.     -- , REGION 'cn-south-1' -- 如 'us-east-1' (可选配置项)
  10.     -- , SCOPE 's3://{bucketName}' -- (可选配置项)
  11. );
  12. -- 查看 secret
  13. SELECT * FROM duckdb_secrets();
  14. -- 删除 secret
  15. -- DROP SECRET s3_secret_qiniu; -- 或 删除持久化的密钥: DROP PERSISTENT SECRET s3_secret_qiniu;
复制代码
:注:默认情况下,会将持久化的密码信息(未加密)写入 ~/.duckdb/stored_secrets 目录。要更改秘密目录,请执行
  1. SET secret_directory = 'path/to/my_secrets_dir';
复制代码

  • 查询远程对象存储中指定 parquet 文件的数据
  1. -- 从s3查询 parquet 文件的数据
  2. select * from read_parquet('s3://{bucketName}/dataset/tb_demo.parquet')
  3. /**
  4. col_0|col_1|col_2|col_3|
  5. -----+-----+-----+-----+
  6.     1|    2|    3|    4|
  7.     5|    6|    7|    8|
  8.     9|   10|   11|   12|
  9.    13|   14|   15|   16|
  10. **/
复制代码
8.png

参数管理


  • 查看参数
  1. D select name,value from duckdb_settings();
  2. name                                       |value
  3. -------------------------------------------+-----
  4. Calendar                                   |grego
  5. TimeZone                                   |Asia/
  6. access_mode                                |autom
  7. allocator_background_threads               |false
  8. allocator_bulk_deallocation_flush_threshold|512.0
  9. allocator_flush_threshold                  |128.0
  10. allow_community_extensions                 |true
  11. allow_extensions_metadata_mismatch         |false
  12. allow_persistent_secrets                   |true
  13. allow_unredacted_secrets                   |false
  14. allow_unsigned_extensions                  |false
  15. allowed_directories                        |[]   
  16. allowed_paths                              |[]   
  17. arrow_large_buffer_size                    |false
  18. arrow_lossless_conversion                  |false
  19. arrow_output_list_view                     |false
  20. ...
  21. disabled_optimizers                        |     
  22. duckdb_api                                 |jdbc
  23. dynamic_or_filter_threshold                |50   
  24. enable_curl_server_cert_verification       |true
  25. ...
复制代码

  • 修改参数
  1. D set threads=10;
复制代码

  • 查看单个参数
  1. D SELECT current_setting('threads') AS threads;
  2. +---------+
  3. | threads |
  4. +---------+
  5. | 10    |
  6. +---------+
复制代码
Pragma 扩展


  • PRAGMA 语句是DuckDB从SQLite中采用的SQL扩展。


  • PRAGMA语句可以以与常规SQL语句类似的方式发出。
  • PRAGMA命令可能会改变数据库引擎的内部状态,并可能影响引擎的后续执行或行为
数据库信息


  • 数据库信息
  1. -- 数据库信息
  2. D PRAGMA database_list;
  3. +------+------+---------------------------------------+
  4. | seq  | name |                 file                  |
  5. +------+------+---------------------------------------+
  6. | 1080 | file | ...file.db                            |
  7. +------+------+---------------------------------------+
  8. 或:
  9. seq|name  |file|
  10. ---+------+----+
  11. 592|memory|    |
复制代码

  • 查看数据库信息(大小)
  1. -- 数据库信息(大小)
  2. D CALL pragma_database_size();
  3. +---------------+---------------+------------+--------------+-------------+-------------+----------+--------------+--------------+
  4. | database_name | database_size | block_size | total_blocks | used_blocks | free_blocks | wal_size | memory_usage | memory_limit |
  5. +---------------+---------------+------------+--------------+-------------+-------------+----------+--------------+--------------+
  6. | file          | 512.0 KiB     | 262144     | 2            | 2           | 0           | 0 bytes  | 256.0 KiB    | 25.0 GiB     |
  7. +---------------+---------------+------------+--------------+-------------+-------------+----------+--------------+--------------+
复制代码
查看表信息


  • 查看所有表信息
  1. -- 所有表信息
  2. D PRAGMA show_tables;
  3. +------+
  4. | name |
  5. +------+
  6. | t1   |
  7. | t2   |
  8. | test |
  9. +------+
复制代码

  • 查看表详细信息
  1. -- 表详细信息
  2. D PRAGMA show_tables_expanded;
  3. +----------+--------+------+--------------+--------------------+-----------+
  4. | database | schema | name | column_names |    column_types    | temporary |
  5. +----------+--------+------+--------------+--------------------+-----------+
  6. | file     | main   | t1   | [a, b]       | [INTEGER, INTEGER] | false     |
  7. | file     | main   | t2   | [a, b]       | [INTEGER, INTEGER] | false     |
  8. | file     | main   | test | [i]          | [INTEGER]          | false     |
  9. +----------+--------+------+--------------+--------------------+-----------+
复制代码

  • 表结构
  1. -- 表结构
  2. D PRAGMA table_info('t1');
  3. +-----+------+---------+---------+------------+-------+
  4. | cid | name |  type   | notnull | dflt_value |  pk   |
  5. +-----+------+---------+---------+------------+-------+
  6. | 0   | a    | INTEGER | false   |            | false |
  7. | 1   | b    | INTEGER | false   |            | false |
  8. +-----+------+---------+---------+------------+-------+
复制代码
查看函数信息


  • 查看函数信息
  1. -- 函数信息
  2. D PRAGMA functions;
  3. D PRAGMA functions;
  4. ┌────────────┬─────────┬────────────────────────┬─────────┬─────────────┬──────────────┐
  5. │    name    │  type   │       parameters       │ varargs │ return_type │ side_effects │
  6. │  varchar   │ varchar │       varchar[]        │ varchar │   varchar   │   boolean    │
  7. ├────────────┼─────────┼────────────────────────┼─────────┼─────────────┼──────────────┤
  8. │ !__postfix │ SCALAR  │ [INTEGER]              │         │ HUGEINT     │ false        │
  9. │ !~~        │ SCALAR  │ [VARCHAR, VARCHAR]     │         │ BOOLEAN     │ false        │
  10. │ !~~*       │ SCALAR  │ [VARCHAR, VARCHAR]     │         │ BOOLEAN     │ false        │
  11. │ %          │ SCALAR  │ [SMALLINT, SMALLINT]   │         │ SMALLINT    │ false        │
  12. │ %          │ SCALAR  │ [UBIGINT, UBIGINT]     │         │ UBIGINT     │ false        │
  13. │ %          │ SCALAR  │ [UINTEGER, UINTEGER]   │         │ UINTEGER    │ false        │
复制代码
版本与平台
  1. -- 版本与平台
  2. D PRAGMA version;
  3. +-----------------+------------+
  4. | library_version | source_id  |
  5. +-----------------+------------+
  6. | v0.10.1         | 4a89d97db8 |
  7. +-----------------+------------+
  8. D PRAGMA platform;
  9. +---------------+
  10. |   platform    |
  11. +---------------+
  12. | windows_amd64 |
  13. +---------------+
复制代码
其他(Profiling/Optimizer/StorageInfo)
  1. -- Profiling
  2. PRAGMA enable_profiling;
  3. SET profiling_mode = 'detailed';
  4. SET enable_profiling = 'query_tree';    logical query plan:
  5. SET enable_profiling = 'query_tree_optimizer';    physical query plan:
  6. PRAGMA disable_profiling;
  7. -- Optimizer
  8. PRAGMA disable_optimizer;
  9. PRAGMA enable_optimizer;
  10. -- Storage Info
  11. D PRAGMA storage_info('t1');
  12. +--------------+-------------+-----------+-------------+------------+--------------+-------+-------+--------------+------------------------------------------------------+-------------+------------+----------+--------------+--------------+
  13. | row_group_id | column_name | column_id | column_path | segment_id | segment_type | start | count | compression  |  stats                                               | has_updates | persistent | block_id | block_offset | segment_info |
  14. +--------------+-------------+-----------+-------------+------------+--------------+-------+-------+--------------+------------------------------------------------------+-------------+------------+----------+--------------+--------------+
  15. | 0            | a           | 0         | [0]         | 0          | INTEGER      | 0     | 3     | Uncompressed | [Min: 1, Max: 3][Has Null: false, Has No Null: true] | false       | true       | 1        | 0            |              |
  16. | 0            | a           | 0         | [0, 0]      | 0          | VALIDITY     | 0     | 3     | Constant     | [Has Null: false, Has No Null: true]                 | false       | true       | -1       | 0            |              |
  17. | 0            | b           | 1         | [1]         | 0          | INTEGER      | 0     | 3     | Uncompressed | [Min: 1, Max: 3][Has Null: false, Has No Null: true] | false       | true       | 1        | 16           |              |
  18. | 0            | b           | 1         | [1, 0]      | 0          | VALIDITY     | 0     | 3     | Constant     | [Has Null: false, Has No Null: true]                 | false       | true       | -1       | 0            |              |
  19. +--------------+-------------+-----------+-------------+------------+--------------+-------+-------+--------------+------------------------------------------------------+-------------+------------+----------+--------------+--------------+
复制代码
性能调优


  • DuckDB 性能调优主要涉及到参数、执行计划等。
尤其是观察 filter 和 projections 下推。
这里简单说明下使用 Explain 命令查看执行计划
查看执行计划
  1. -- 查看执行计划
  2. D explain select deptno,count(*) from big_emp group by deptno;
  3. ┌─────────────────────────────┐
  4. │┌───────────────────────────┐│
  5. ││       Physical Plan                             ││
  6. │└───────────────────────────┘│
  7. └─────────────────────────────┘
  8. ┌───────────────────────────┐
  9. │         PROJECTION                            │
  10. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  11. │__internal_decompress_integ                           │
  12. │     ral_integer(#0, 1)                           │
  13. │             #1                            │
  14. └─────────────┬─────────────┘
  15. ┌─────────────┴─────────────┐
  16. │   PERFECT_HASH_GROUP_BY                            │
  17. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  18. │             #0                            │
  19. │        count_star()                           │
  20. └─────────────┬─────────────┘
  21. ┌─────────────┴─────────────┐
  22. │         PROJECTION                            │
  23. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  24. │           deptno                            │
  25. └─────────────┬─────────────┘
  26. ┌─────────────┴─────────────┐
  27. │         PROJECTION                            │
  28. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  29. │__internal_compress_integra                           │
  30. │     l_usmallint(#0, 1)                           │
  31. └─────────────┬─────────────┘
  32. ┌─────────────┴─────────────┐
  33. │         SEQ_SCAN                             │
  34. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  35. │          big_emp                            │
  36. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  37. │           deptno                            │
  38. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  39. │        EC: 1000000                            │
  40. └───────────────────────────┘
  41. -- 关闭优化器后,再观察看下
  42. D PRAGMA disable_optimizer;
  43. D explain select deptno,count(*) from big_emp group by deptno;
  44. ┌─────────────────────────────┐
  45. │┌───────────────────────────┐│
  46. ││       Physical Plan                            ││
  47. │└───────────────────────────┘│
  48. └─────────────────────────────┘
  49. ┌───────────────────────────┐
  50. │       HASH_GROUP_BY                            │
  51. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  52. │             #0                            │
  53. │        count_star()                           │
  54. └─────────────┬─────────────┘
  55. ┌─────────────┴─────────────┐
  56. │         PROJECTION                            │
  57. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  58. │           deptno                            │
  59. └─────────────┬─────────────┘
  60. ┌─────────────┴─────────────┐
  61. │         SEQ_SCAN                             │
  62. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  63. │          big_emp                            │
  64. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  65. │   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                 │
  66. │        EC: 1000000                            │
  67. └───────────────────────────┘
复制代码
密钥管理


  • 推荐文献


  • 密钥管理 - DuckDB


  • 支持管理的密钥类型
密钥类型服务 / 协议扩展azureAzure Blob 存储azureducklakeDuckLakeducklakegcsGoogle Cloud StoragehttpfshttpHTTP 和 HTTPShttpfshuggingfaceHugging FacehttpfsmysqlMySQLmysqlpostgresPostgreSQLpostgresr2Cloudflare R2httpfss3AWS S3httpfs插件管理

别名:扩展管理


  • 推荐文献


  • 插件管理 - DuckDB
查看插件


  • 获取扩展列表,请使用 duckdb_extensions 函数
  1. SELECT
  2.         extension_name, installed, description
  3. FROM duckdb_extensions();
复制代码
扩展名称已安装描述arrow否Apache Arrow 和 DuckDB 之间的零拷贝数据集成autocomplete否在 Shell 中添加自动补全支持………
此列表将显示哪些扩展可用、哪些扩展已安装版本以及安装位置等信息。
此列表包含大多数(但并非所有)可用的核心扩展。有关完整列表,请参阅我们维护的核心扩展列表
9.png

内置扩展


  • DuckDB 的二进制分发版标准包含一些内置扩展。它们静态链接到二进制文件中,可以直接使用。
例如,要使用内置的 json 扩展来读取 JSON 文件
  1. SELECT * FROM 'test.json';
复制代码

  • 为了使 DuckDB 分发包轻量化,只有少数必需的扩展是内置的,具体取决于不同的分发版本。
哪个扩展在哪个平台上是内置的,已在核心扩展列表中说明。
10.png

安装更多扩展


  • 可以通过SQL命令安装DuckDB的扩展插件,这类插件程序一般只需要运行一次。
  • 要使非内置扩展在 DuckDB 中可用,需要执行两个步骤


  • 扩展安装是下载扩展二进制文件并验证其元数据的过程。
在安装过程中,DuckDB 会将下载的扩展和一些元数据存储在本地目录中。DuckDB 随后可以从该目录中按需加载扩展。这意味着安装只需进行一次。


  • 扩展加载是将二进制文件动态加载到 DuckDB 实例中的过程。
DuckDB 会在本地扩展目录中搜索已安装的扩展,然后加载它以使其功能可用。这意味着每次重新启动 DuckDB 时,所有已使用的扩展都需要(重新)加载。


  • 使 DuckDB 执行可安装扩展的安装和加载步骤有两种主要方法:显式方式和通过自动加载
显式 INSTALL 和 LOAD


  • 在 DuckDB 中,扩展也可以显式安装和加载。非自动加载和可自动加载的扩展都可以通过这种方式安装。要显式安装和加载扩展,DuckDB 提供了专用的 SQL 语句 LOAD 和 INSTALL。例如,要安装和加载 spatial 扩展,请运行
  1. INSTALL spatial;
  2. LOAD spatial;
复制代码
使用这些语句,DuckDB 将确保 spatial 扩展已安装(如果已安装则忽略 INSTALL 语句),然后继续 LOAD spatial 扩展(如果已加载则再次忽略该语句)。
扩展存储库


  • 可以选定要安装扩展的存储库,方法是将 FROM repository 附加到 INSTALL / FORCE INSTALL 命令。此存储库可以是别名,例如 community,也可以是作为单引号字符串提供的直接 URL。
  • 安装/加载扩展后,可以使用 duckdb_extensions 函数获取更多信息。
自动加载扩展


  • 对于许多 DuckDB 的核心扩展,不需要显式加载和安装。DuckDB 包含一个自动加载机制,可以在核心扩展在查询中使用时立即安装和加载它们。例如,当运行
  1. SELECT
  2.     *
  3. FROM 'https://raw.githubusercontent.com/duckdb/duckdb-web/main/data/weather.csv';
复制代码

  • DuckDB 将自动安装并加载 httpfs 扩展。无需显式的 INSTALL 或 LOAD 语句。
  • 并非所有扩展都可以自动加载
这可能有多种原因:一些扩展会对正在运行的 DuckDB 实例进行多项更改,使得自动加载在技术上尚不可能。对于其他扩展,由于它们修改 DuckDB 行为的方式,更倾向于用户在使用前显式选择加入该扩展。
要查看哪些扩展可以自动加载,请查看核心扩展列表。
社区扩展


  • DuckDB 支持安装第三方社区扩展。


  • 例如,您可以通过以下方式安装 avro 社区扩展:
  1. INSTALL avro FROM community;
复制代码

  • 社区扩展由社区成员贡献,但它们在集中式存储库中构建、签名和分发。
更新扩展


  • 内置扩展由于其内置于 DuckDB 二进制文件的性质而与 DuckDB 版本绑定,而可安装的扩展可以且确实会接收更新。为确保所有当前安装的扩展都处于最新版本,请调用
  1. UPDATE EXTENSIONS;
复制代码

  • 有关扩展版本的更多详细信息,请参阅扩展版本控制页面。
开发扩展


  • 核心扩展使用的相同 API 也可用于开发扩展。这允许用户扩展 DuckDB 的功能,使其最适合其领域。用于创建扩展的模板可在 extension-template 存储库中找到。此模板还包含有关如何开始构建自己的扩展的一些文档。
使用扩展


  • 请参阅安装说明和高级安装方法页面。
Z FAQ for DuckDB

Q: DBeaver 连接 DuckDB


  • 数据库 - 新建数据库连接  - DuckDB - 下一步
    11.png

  • 路径(输入: :memory - 下一步
当然,也可输入持久化的duckdb数据库文件路径。
12.png

13.png


  • 下载 duckdb 驱动包
14.png

即安装完成:
15.png


  • 尝试使用
  1. select version();
  2. -- v1.4.3
  3. select * from read_csv("D:\Program-Data\DuckDB\datasources\tb_student.csv")
复制代码
16.png

tb_student.csv
  1. id,name,birthdate,comment
  2. 1,jack,2005-07-01,""
  3. 2,jane,2004-09-28,""
复制代码
Q: 使用 DuckLake 和 DuckDB 构建轻量级的 S3 数据湖?

此方案,未亲测。


  • 推荐文献


  • 使用 DuckLake 和 DuckDB 构建 S3 数据湖实战指南 - CSDN
由 DuckDB 和 DuckLake 组成的轻量级数据湖方案,旨在解决传统数据湖(如Hadoop+Hive)元数据管理复杂、查询性能低及厂商锁定等问题。
该方案为中小规模数据湖场景提供了简单、高性能且无厂商锁定的替代选择。
什么是 DuckLake 和 DuckDB?


  • 在现代数据架构中,数据湖(Data Lake) 和 湖仓一体(Lakehouse) 已成为存储和管理大规模结构化与非结构化数据的核心方案。然而,传统的数据湖(如 Hadoop + Hive)往往存在元数据管理复杂、查询性能低、依赖特定厂商等问题。
  • DuckDB 是一个高性能的嵌入式分析数据库,支持 SQL 查询和向量化执行,特别适合本地和云环境下的数据分析。而 DuckLake 是一个基于 DuckDB 的轻量级表格式,它将元数据存储在 SQL 数据库(如 DuckDB)中,而实际数据则存储在开放格式(如 Parquet)的云存储(如 S3、GCS、Azure Blob Storage)上。
  • DuckLake 的核心优势:


  • ✅ ​​简单易用​​:所有元数据管理通过 SQL 完成,无需复杂配置。
  • ✅ ​​高性能​​:元数据操作极快,查询性能优异。
  • ✅ ​​开放标准​​:数据存储在 Parquet 格式,元数据可移植。
  • ✅ ​​ACID 事务支持​​:支持 schema 演进、时间旅行(Time Travel)等高级功能。
环境准备:安装 DuckDB 并加载扩展


  • 确保已安装 DuckDB(官方下载地址)。然后,在 DuckDB 中加载必要的扩展以支持云存储和 DuckLake:
  1. -- 安装并加载 AWS S3 支持
  2. INSTALL aws;
  3. LOAD aws;
  4. -- 安装 HTTP 文件系统支持(可选,用于远程数据访问)
  5. INSTALL httpfs;
  6. LOAD httpfs;
  7. -- 安装 Parquet 支持(用于读取/写入 Parquet 文件)
  8. INSTALL parquet;
  9. LOAD parquet;
  10. -- 安装 DuckLake 扩展
  11. INSTALL ducklake;
  12. LOAD ducklake;
复制代码

  • 配置 AWS 凭证
DuckDB 支持从环境变量或直接加载 AWS 凭证。推荐使用环境变量方式(更安全):
  1. # 在终端设置 AWS 凭证(Linux/macOS)
  2. export AWS_ACCESS_KEY_ID="your-access-key"
  3. export AWS_SECRET_ACCESS_KEY="your-secret-key"
  4. export AWS_REGION="us-east-1"  # 替换为你的 S3 区域
复制代码
或者在 DuckDB 中直接加载凭证:
  1. -- 直接加载 AWS 凭证(不推荐生产环境使用)
  2. CALL load_aws_credentials();
复制代码
创建 DuckLake 目录并连接 S3


  • DuckLake 使用 目录(Catalog) 管理表元数据。
我们可以在 S3 上创建一个 DuckLake 目录:
  1. -- 在 S3 上创建 DuckLake 目录
  2. ATTACH 'ducklake:metadata.ducklake' (
  3.   DATA_PATH 's3://your-bucket/your-prefix/'  -- 替换为你的 S3 路径
  4. );
复制代码


  • metadata.ducklake 是元数据文件名(DuckDB 会自动管理)。
  • DATA_PATH 指定 S3 存储路径,所有 Parquet 数据将存储在此目录下。
创建表、插入数据、更新和删除

(1) 创建表
  1. -- 在 DuckLake 目录中创建表
  2. CREATE TABLE IF NOT EXISTS metadata.customers (
  3.     customer_id INTEGER,
  4.     first_name STRING,
  5.     last_name STRING,
  6.     email STRING,
  7.     city STRING,
  8.     created_at TIMESTAMP
  9. );
复制代码
(2) 插入数据
  1. -- 插入示例数据
  2. INSERT INTO metadata.customers VALUES
  3.   (1, 'Alice', 'Smith', 'alice@example.com', 'New York', CURRENT_TIMESTAMP),
  4.   (2, 'Bob', 'Johnson', 'bob@example.com', 'San Francisco', CURRENT_TIMESTAMP);
复制代码
(3) 更新数据
  1. -- 更新 Bob 的城市
  2. UPDATE metadata.customers
  3. SET city = 'Los Angeles'
  4. WHERE customer_id = 2;
复制代码
(4) 删除数据
  1. -- 删除 Alice 的记录
  2. DELETE FROM metadata.customers WHERE customer_id = 1;
复制代码
(5) 查询数据
  1. -- 查询所有客户
  2. SELECT * FROM metadata.customers;
复制代码
高级功能:ACID 事务 & 时间旅行


  • DuckLake 支持 ACID 事务,确保数据一致性。例如:
  1. -- 开启事务
  2. BEGIN TRANSACTION;
  3. -- 插入新数据
  4. INSERT INTO metadata.customers VALUES
  5.   (3, 'Charlie', 'Brown', 'charlie@example.com', 'Chicago', CURRENT_TIMESTAMP);
  6. -- 更新数据
  7. UPDATE metadata.customers
  8. SET city = 'Seattle'
  9. WHERE customer_id = 2;
  10. -- 提交事务
  11. COMMIT;
复制代码

  • 时间旅行(Time Travel) 允许查询历史数据版本:
  1. -- 查询 1 小时前的数据(假设 DuckLake 支持时间旅行)
  2. SELECT * FROM metadata.customers AT TIMESTAMP '2025-05-28 12:00:00';
复制代码
注意:时间旅行功能可能需要额外配置,具体取决于 DuckLake 版本。
小结:为什么选择 DuckLake + DuckDB?

特性DuckLake + DuckDB传统数据湖 (Hive/Hadoop)元数据管理SQL 管理,简单高效依赖 Hive Metastore, 复杂查询性能向量执行,极快依赖 MapReduce/Spark, 较慢数据格式Parquet(开放标准)Parquet/ORC(但依赖特定工具)ACID 支持完整支持部分支持(如 Delta Lake)厂商锁定无锁定,纯开源可能依赖 Hadoop/Spark 生态

  • DuckLake + DuckDB 提供了一种 轻量级、高性能、开源 的数据湖解决方案,特别适合:


  • 本地开发(嵌入式 DuckDB)
  • 云原生分析(S3/GCS 存储)
  • 需要 ACID 事务的场景
Y 推荐文献


  • DuckDB


  • 安装包 https://duckdb.org/install/
  • Guide https://duckdb.org/docs/stable/guides/overview
  • SQL 介绍 https://duckdb.org/docs/stable/sql/introduction
  • Github https://github.com/duckdb/duckdb


  • Apache Parquet


  • [文件格式/数据存储] Apache Parquet:开源、高效的列式存储文件格式协议 - 博客园/千千寰宇
CASE : DuckDB 数据库 On Parquet
CASE : 二维数组保存为 parquet


  • Apache Doris


  • Aliyun OSS - Doris


  • 其他文献


  • 别再被“大数据”忽悠了:DuckDB,一场属于单机的复仇 - Weixin 2025.12
  • 数据Infra:基于 DuckDB 设计的分布式数据平台 - Weixin/DuckNest
注:这是一次思想实验,是与 DuckLake 数据仓库相反的创新路径


  • 【R数据库】duckdb/duckplyr包:整洁操作数据库 - Weixin
X 参考文献


  • 1 分钟安装 DuckDB - 腾讯云 2024.11.21
  • 嵌入式分析型数据库DuckDB - Zhihu 2025.1.27
  • DuckDB 读写远程s3, oss, http Parquet 文件 - modb.pro 2024.1.25
    本文作者:        千千寰宇   
    本文链接:         https://www.cnblogs.com/johnnyzen   
    关于博文:评论和私信会在第一时间回复,或直接私信我。   
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA     许可协议。转载请注明出处!
    日常交流:大数据与软件开发-QQ交流群: 774386015        【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!   

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册