DuckDB 2.0.0 中的隐藏亮点
2026-10-29
5 分钟阅读
DuckDB 团队
摘要:我们重点介绍 DuckDB 2.0.0 中一些随版本发布但未进入发布公告的较小功能。
上周我们发布了 DuckDB 2.0.0 LTS"Cinnamon Teal",这是迄今为止功能最丰富的一次版本发布。公告涵盖了头条内容:Quack 协议、异步 I/O、一等公民 VARIANT 类型、agent 模式、PEG 解析器和触发器。一如既往,完整变更列表请查阅发布说明,安装或升级说明请参阅安装页面。
如此规模的版本包含许多从未进入公告的较小改进。本文重点介绍其中几个亮点。要查找 2.0 中所有新功能的文档,请参阅"2.0 文档新内容"页面。
DuckDB 2.0 中未被充分宣传的功能
用 SHOW 查看配置设置
SHOW 语句现在可以像 PostgreSQL 那样按名称打印配置设置------当该名称不指向表时:
sql
SET threads = 42;
SHOW threads;
threads
42
当表和设置同名时,DuckDB 默认描述该表。你可以通过 show_behavior 设置控制此行为,它接受 'auto'(默认)、'table' 或 'setting'。
SECURE VIEW(安全视图)
普通视图可能通过统计信息和查询计划泄露其底层表的信息,例如通过 stats() 函数。新的 SECURE VIEW 不会:
sql
CREATE SECURE VIEW users AS
SELECT username
FROM all_users
WHERE access_level = 'standard';
安全视图对这些内部信息返回 NULL,并在 EXPLAIN ANALYZE 中显示 Secure View 节点,因此查询计划无法被用来重建视图过滤掉的行。
regexp_extract 中的正则选项
regexp_extract 函数新增了一个重载,将正则选项作为第三个参数,且不需要捕获组。例如,现在可以在一次调用中实现不区分大小写匹配:
sql
SELECT regexp_extract('ABC', 'abc', 'i'); -- ABC
设置序列值
序列新增了 PostgreSQL 风格的 setval 函数,可将序列重置为给定值,这在批量加载后很有用:
sql
CREATE SEQUENCE serial START 1;
SELECT setval('serial', 42);
SELECT nextval('serial');
nextval
43
默认情况下,setval 之后的下一个值是 value + increment。将可选的第三个参数 is_called 传为 false,可使下一次 nextval 返回 value 本身。
会话变量作为默认参数值
预处理语句现在可以在执行时未提供命名参数的情况下,回退到同名会话变量:
sql
SET VARIABLE multiplier = 10;
SET VARIABLE x = 42;
PREPARE compute AS SELECT $multiplier * $x AS result;
EXECUTE compute;
result
420
显式参数始终优先于变量;由于回退是在执行时解析的,更改变量后重新执行会获取新值。
自定义分区路径
写入分区数据时,PARTITION_BY 子句按 Hive 约定将每个分区写入 col=value 子目录。新的 PARTITION_PATH 选项让你完全控制每个分区写入的子目录,使用基于分区列的表达式:
sql
COPY orders TO 'orders'
(FORMAT parquet,
PARTITION_BY (year),
PARTITION_PATH CASE
WHEN year < 2020 THEN 'archive'
ELSE 'recent/' || year
END);
该表达式对每个分区求值一次,其结果必须是相对路径,且不能包含 .. 段。配套的 ORDER_BY 复制选项在写入前对行排序;与 PARTITION_BY 结合使用时,在每个分区内排序:
sql
COPY orders TO 'orders'
(FORMAT parquet,
PARTITION_BY (year, month),
ORDER_BY (amount DESC NULLS LAST));
写入 GeoJSON
空间扩展现在可以直接用 COPY ... (FORMAT GEOJSON) 写入 GeoJSON,生成 FeatureCollection;或用 FORMAT GEOJSONL 生成按行分隔的 feature:
sql
COPY (SELECT 'POINT(0 1)'::GEOMETRY AS geom, 10 AS my_field)
TO 'test.json' (FORMAT GEOJSON);
可选的 ID_COLUMN 和 GEOMETRY_COLUMN 选项用于选择哪些列成为 feature 的 id 和 geometry。读取 GeoJSON 的内容见"加载 JSON"页面。
CLI 中的生活质量改进
美化打印的 .schema
从 DuckDB 2.0 起,.schema 点命令默认美化打印并高亮其输出,使阅读数据库模式容易得多。如果你更喜欢早期的单行形式(例如为了逐字复制语句),请使用 --no-indent(或其别名 --no-format):
bash
duckdb mydata.duckdb ".schema --no-indent"
命令历史
CLI 现在以两种方式暴露其命令历史。.history 点命令显示之前执行的语句并带语法高亮,可选限制为最近 N 条:
.history 10
同样的信息也可通过 shell_history() 表函数以表的形式获取,因此你可以用 SQL 查询自己的历史:
sql
SELECT sql
FROM shell_history()
WHERE sql ILIKE '%copy%';
Python Appender
逐行插入很慢,而构建巨大的 INSERT 语句又很别扭。Python appender 收集行并在一次操作中一起写入:
python
with con.appender("people") as appender:
appender.append_row(1, "Mark")
appender.append_rows([(2, "Hannes"), (3, "Gabor")])
with 块退出时会刷新缓冲的行。对于已存在于 DataFrame 或 Arrow 表中的数据,INSERT INTO ... SELECT 仍然更快,但对于 Python 代码即时产生的行,appender 是理想选择。
网络动态
DuckDB 周围的生态系统持续增长:许多项目既使用 DuckDB 构建,也在 DuckDB 内构建。由 David Gasquez 维护的社区驱动的 awesome-duckdb 仓库将这些扩展、集成和文章收集在一处,是探索人们正在构建什么的好起点。
这些只是 DuckDB 2.0 中较小功能的一部分。其余内容请参阅发布说明和核心扩展概览。一如既往,感谢使本次发布成为可能的贡献者们!