DuckDB 推出原生 C# 扩展包, 笼络 .NET 生态
本期播客
DuckDB 推出原生 C# 扩展包, 笼络 .NET 生态
过去,数据库扩展开发常常意味着:性能要原生,开发就得向 C/C++ 低头。
现在 DuckDB 给出的新答案是:你可以继续要原生性能,但不一定继续忍受底层开发的高门槛。
很多人还没意识到,DuckDB 这次放出来的,不只是一个“给 .NET 开发者更友好”的工具,而是在动数据库生态的一条老规矩:数据库扩展,究竟应该由谁来写、用什么语言写、以什么速度进入业务场景。
DuckDB 最新发布的 DuckDB.ExtensionKit,把 C# 带进了 DuckDB 原生扩展开发链路,而且不是“套壳调用”,而是基于 DuckDB 稳定的 C Extension API,加上 .NET Native AOT,最终产出可直接被 DuckDB 加载的原生扩展二进制。从 DuckDB 视角看,它和 C/C++ 写出来的原生扩展没有本质区别。
这件事为什么重要?
因为它击中了数据库落地里一个长期被忽视的矛盾:业务创新的速度,远快于数据库内核团队开放能力的速度。
1. 真正稀缺的,不是“函数能力”,而是“把能力放进数据库”的成本
对 DBA、架构师来说,数据库扩展从来不是新鲜概念。文件格式支持、新类型、新函数、外部系统集成,这些都可以通过扩展完成。DuckDB 自己大量能力也是通过扩展机制提供的,例如 json 扩展处理 JSON,postgres 扩展对接 PostgreSQL;同时它也已经形成社区扩展生态,社区扩展仓库自 2024 年夏季开始提供安装分发。
但问题一直不在“能不能扩”,而在“谁能扩、多久能扩、扩完谁维护”。
传统 DuckDB 扩展开发主要走 C++ API,这条路能力强,但和内部 API 耦合紧,DuckDB 版本一变,扩展就可能跟着动;官方也同时提供了基于 C Extension API 的实验模板,目标就是提供更稳定、向后兼容的接口。只是,哪怕走 C API,开发者仍然得面对低层接口、手动内存管理和大量样板代码。
这就是第一性原理:
数据库扩展的瓶颈,从来不是“数据库不支持”,而是“把外部能力安全、稳定、低成本地装进数据库执行面”太难。
只要这个前提成立,DuckDB.ExtensionKit 就不是“锦上添花”,而是在降低数据库能力供给侧门槛。
2. 对 DBA/架构师来说,这不是语言新闻,而是治理模型变化
很多架构师容易把这类消息理解成:“哦,C# 开发者也能写 DuckDB 插件了。”
这理解太浅。
真正该看到的是:数据库扩展的供给人群,被大幅放大了。
DuckDB 当前已经支持扩展在 Python、R 等客户端加载,核心和社区扩展还覆盖 macOS、Windows、Linux,并支持 AMD64 与 ARM64。DuckDB 主仓库 GitHub Star 已到 3.6 万以上,这意味着它早已不是实验室玩具,而是一个快速扩张的分析型数据底座。
一旦扩展开发从“少数懂 C/C++ 和数据库内部机制的人”扩展到“.NET 生态的大量工程师”,会发生什么?
第一,行业能力更容易数据库内嵌。
文章里的示例很典型:直接用现成的 .NET JWT 库,把 JWT claim 解析做成 DuckDB 的标量函数和表函数,二十几行代码就能把应用层常见逻辑下沉进 SQL。
第二,数据库边界会继续向应用侧长出来。
过去很多逻辑在 ETL、应用服务、中间层做;以后更多会直接以内联函数、表函数的方式进入查询执行面。对业务来说,这会减少数据搬运;对治理来说,这会增加扩展审计、版本控制、兼容测试的压力。
第三, 平台团队的职责会从“自己写能力”转向“制定扩展准入规则” 。
因为门槛一降,问题就不再是“没人写”,而是“谁都能写,怎么控风险”。
这才是 DBA 和架构师真正要警惕的点:
当数据库扩展民主化,治理必须先于自由。
3. 对应用开发者来说,最值钱的不是“能写扩展”,而是“终于能复用你的技术栈”
DuckDB.ExtensionKit 的核心价值,不是教你用另一种语言重复造轮子,而是让你把 .NET 生态里已经成熟的库、团队经验、工程体系,直接带进 DuckDB 扩展开发。官方描述得很明确:它提供了类型安全的高层 API、源码生成器自动生成入口和初始化样板,并通过 Native AOT 发布成不依赖 .NET 运行时的原生扩展。
这意味着什么?
意味着如果你的团队本来就在 C#/.NET 上沉淀了大量领域逻辑——加密、令牌处理、规则引擎、文本处理、企业协议适配——以前你要把它们塞进数据库,要么重写成 C/C++,要么退而求其次继续放在数据库外面。
现在多了一条新路径:直接把成熟业务能力封装成 DuckDB 可加载扩展。
这对“应用开发者即数据库用户”尤其关键。
因为他们真正讨厌的不是 SQL,而是:
每次数据库能力不够时,都得在应用层再包一圈。
当数据库内可以安全地长出业务专属函数时,数据处理链路会更短,代码职责会更集中,重复数据拷贝也可能更少。这种收益,远比“语言亲切感”本身更现实。
4. 但别急着神化:这不是“C# 战胜 C++”,而是“稳定 ABI + AOT”找到一个新平衡点
这波最容易被带偏的舆论,是把它写成“高阶语言全面替代底层语言”。
这不严谨。
DuckDB.ExtensionKit 能成立,不是因为 C# 突然变成了数据库内核语言,而是因为它踩中了两个关键条件:
第一,DuckDB 提供了稳定的 C Extension API 作为边界。
DuckDB 的 C API 本身就是官方稳定接口,当前文档显示最新稳定版本为 1.5.0。扩展套件并不是绕开底层,而是老老实实贴着这个 ABI 边界工作。
第二,**.NET Native AOT 把托管代码提前编译成了原生二进制**。
这一步非常关键。否则你写出来的只是“数据库调用托管运行时”的桥,而不是能被数据库直接装载的原生扩展。官方明确说明,最终产物没有加载时的托管运行时依赖。
所以,本质不是“C# 更强了”,而是:
只要数据库给出稳定 ABI,语言生态又能生成真正原生工件,高层语言就有资格进入数据库扩展开发。
这条规律不止适用于 C#。
今天是 .NET,明天可能是更多具备原生交付能力的语言生态。DuckDB 这次证明的是方向,而不只是一个工具包。
5. 条件一旦变化,结论也要跟着变
这里必须把前提讲透,不然文章就容易变成技术鸡血。
前提 A:你要的是“扩展开发门槛下降”,不是“所有数据库内核工作都高层化”
如果你的需求是做非常深的执行器改造、复杂优化器逻辑、与 DuckDB 内部实现强耦合的能力,那 C++ 仍然是主战场。因为 ExtensionKit 当前覆盖的能力并不完整,而且官方明确说它仍处于实验阶段,并非所有 DuckDB 扩展能力都已暴露出来。
前提 B:你接受“原生扩展天然平台相关”
ExtensionKit 依赖 Native AOT,这意味着你得分别为 linux-x64、osx-arm64、win-x64 等目标平台构建产物。这个限制不是它独有,而是所有原生扩展的共同现实。DuckDB 官方扩展文档也强调,核心与社区仓库分发的扩展本身就是跨 OS、跨架构构建与测试的。
前提 C:你所在团队真的有 .NET 资产可复用
如果你的团队不是 .NET 技术栈,也没有相关库资产,那它带来的收益就会明显下降。此时你感受到的不是“效率提升”,而只是“多了一个可选项”。
也就是说,我的观点并不是“所有团队都该立刻用 C# 写 DuckDB 扩展”,而是:
对拥有 .NET 研发能力、又想把业务逻辑更靠近数据执行面的团队来说,这是一条非常现实的新通道。
如果这个前提崩塌,最合理的观点就应当变成:继续用现有 C/C++ 模板,或者优先消费成熟核心/社区扩展,而不是盲目追新。
6. 这件事对企业最现实的影响:数据库能力交付会越来越像应用交付
DuckDB 社区扩展仓库从 2024 年夏季开始提供安装分发;社区文档也说明,社区扩展目前主要面向最新稳定版 DuckDB 构建和分发,新版本发布前还会同步验证对 stable 和 main 的兼容性。
这意味着企业应该开始用“软件供应链”的眼光看数据库扩展,而不是把它当成零散脚本:
版本要不要锁定? 哪些扩展允许进生产? 谁负责安全审查? 升级 DuckDB 时先测核心能力,还是先测业务扩展兼容性? 是允许团队自研扩展,还是统一进入内部扩展仓库?
以前很多组织没认真想这些,是因为会写扩展的人太少。
现在门槛下降,这套治理迟早要补课。
所以我的判断很直接:
DuckDB.ExtensionKit 的真正意义,不是多了一种开发语言,而是数据库能力开发开始“应用工程化”。
对平台团队,这是治理问题。
对开发者,这是生产力问题。
对企业,这是交付模型问题。
小结
DuckDB 这一步,表面上是在给 C# 开发者发门票;
本质上,是在告诉整个数据库行业一件事:
未来数据库扩展的竞争,不只看谁性能强,还看谁能让更多工程师,在不牺牲原生集成能力的前提下,更快把业务能力装进数据库。
谁先把这件事想明白,谁就不只是“用 DuckDB”,而是在重新设计数据能力的生产方式。
你怎么看?
你觉得数据库扩展开发的未来,会走向“更多高层语言原生化”,还是仍然会牢牢掌握在 C/C++ 手里?欢迎在评论区聊聊。