DuckDB 存储结构:从逻辑表到磁盘 Block
核心结论DuckDB 原生表的主线只有一条Table→ Row Group→ ColumnData→ Column Segment→ DuckDB Block→ Buffer Manager→ Vector / DataChunk表按行划分为 Row GroupRow Group 内按列组织每列拆成可独立压缩的 Column SegmentSegment 映射到固定大小的 DuckDB Block查询时由 Buffer Manager 把 Block 读入内存并解码成 Vector。这里最重要的两个边界是Column Segment逻辑压缩与解码单元。DuckDB Block物理存储、I/O 和缓存单元。ChatGPT Image 2026年7月19日 14_12_10ChatGPT Image 2026年7月19日 13_59_41ChatGPT Image 2026年7月19日 15_51_42示例表全文使用同一张表说明CREATE TABLE events (tenant_id INTEGER,ts TIMESTAMP,payload VARCHAR);3. DuckDB 原生存储层DuckDB 存储层可以用一句话概括表先按行切成 Row Group每个 Row Group 内按列组织成 ColumnData每列再切成若干 Column SegmentSegment 压缩后放进数据库文件的 BlockBlock 由 Buffer Manager 读入内存。Table└── Row Group├── ColumnData A│ ├── Column Segment A0│ └── Column Segment A1└── ColumnData B├── Column Segment B0├── Column Segment B1└── Column Segment B2↓Block ID Block Offset↓.duckdb 数据库文件↓Buffer ManagerParquet逻辑表Table└── 映射为 Parquet File└── Row Group├── Column Chunk A│ ├── Dictionary Page可选│ ├── Data Page A0│ └── Data Page A1└── Column Chunk B├── Dictionary Page可选├── Data Page B0├── Data Page B1└── Data Page B2↓文件偏移file offsets↓.parquet 文件↓Reader / 文件系统 / OS Page Cache需要特别注意DuckDB 原生存储中通常不把物理单位称为传统数据库的“Page”它的核心物理 I/O 单位叫 Block。如果你说的 page 是操作系统的 4 KiB 内存页那么一个 DuckDB Block 通常会覆盖多个 OS page。在常见的 4 KiB OS Page 环境中DuckDB 的 Block 边界是对齐的但这不是对任意操作系统 Page 大小都成立的通用保证。但parquet它也可能一个 Parquet Page 跨多个 OS Page一个 OS Page 同时包含两个相邻 Parquet Page 的字节Parquet Page 的开始位置不和 OS Page 对齐。因为 Parquet Page 是可变长度的文件格式对象而不是固定大小的物理 I/O 页。Parquet 的目标是紧凑存储和跨系统交换因此 Page 通常在 Column Chunk 中连续排列不按 4 KiB 等操作系统页面边界补齐。Parquet 格式不要求 Page 与操作系统页面对齐。Table: eventsRow Group 0Row Group 1tenant_id ColumnDatats ColumnDatapayload ColumnDataSegment T0Segment T1Segment TS0Segment P0Segment P1Block 42Block 43Buffer ManagerVector / DataChunk3.1 Row Group一批连续行Row Group 是表的水平分区。例如events├── Row Group 0行 0 122879├── Row Group 1行 122880 245759└── …它的作用是把大表分成可管理的行范围保存统计信息用于跳过不可能命中的数据提供原生表并行扫描的重要边界为列压缩提供组织范围。Row Group 不是行存。 它只规定一批行号内部仍然按列存储。3.2 ColumnDataRow Group 中的一列在一个 Row Group 内每列对应一个 ColumnDataRow Group 0├── tenant_id ColumnData├── ts ColumnData└── payload ColumnDataColumnData 负责管理该列的Segment 集合扫描位置Scan / Select / Skip统计信息和更新状态。3.3 Column Segment一列中的连续压缩片段一列可以包含多个 Segmentpayload ColumnData├── Segment P0├── Segment P1└── Segment P2一个 Segment 通常包含start / countcompressionstatisticsblock_idblock_offsetsegment_sizeSegment 的行数并不固定。它取决于数据类型、数据宽度、压缩率和 Block 可用空间。因此宽字符串列通常比整数列产生更多 Segment。Segment 与 Block 的对应关系4.1 多个小 Segment 可以共享一个 BlockBlock 42┌──────────────────────────────┐│ Segment T0 offset 0 │├──────────────────────────────┤│ Segment T1 offset 55 KB │├──────────────────────────────┤│ Segment TS0 offset 105KB │├──────────────────────────────┤│ 剩余空间 │└──────────────────────────────┘定位依靠block_id block_offset因此相同 block_id、不同 block_offset多个 Segment 共享一个 Block大 Segment 可能接近独占一个 BlockConstant Segment 可能无需普通数据 Block长字符串或复杂类型可能另外引用溢出或子存储。4.2 读取粒度与解码粒度不同假设查询只需要 Block 42 中的 Segment T1逻辑解码只解码 Segment T1物理读取通常加载整个 Block 42因此DuckDB 可以只解码需要的 Segment但当 Block 尚未在内存中时物理上通常仍需读取该 Segment 所在的完整 Block。这也是优化数据搬运时必须明确的边界。Block 与 Buffer ManagerDuckDB Block 是 .duckdb 文件内部的固定大小物理单元常见默认分配大小约为 256 KiB。.duckdb 文件├── 文件头 / 数据库元数据├── Block 0├── Block 1├── Block 2└── …Buffer Manager 负责把 Block 从文件读入内存缓存和淘汰 BlockPin 当前正在使用的 Block执行软件预取协调数据库页和查询内存。不要混淆概念 含义DuckDB Block DuckDB 自己的物理 I/O 与缓存单元OS Page 操作系统内存页常见为 4 KiBDataChunk 查询执行中的内存批次不是磁盘块一个 256 KiB DuckDB Block 在常见 4 KiB 页系统上覆盖约 64 个 OS Page但 Segment 在 Block 内未必按 OS Page 对齐。一次查询如何读取数据查询SELECT payloadFROM eventsWHERE tenant_id 42;读取路径否是检查 Row Group / Segment 统计读取 tenant_id 所在 Block解码 tenant_id Vector生成 SelectionVector是否有幸存行?payload 执行 Skip读取 payload 所在 Block按 Select 或 Scan 解码 payload输出 DataChunk关键点各列拥有独立扫描状态过滤列可以先读取没有幸存行时载荷列可以 Skip有幸存行时再对载荷列执行 Select 或 Scan但物理读取的基本单位仍然是 Block。回到顶部DuckDB 原生存储与 Parquet 的区别7. 两套层级DuckDB 原生表Table→ Row Group→ ColumnData→ Column Segment→ DuckDB Block→ Buffer ManagerParquet 文件File→ Row Group→ Column Chunk→ Dictionary Page / Data Page→ 文件字节区间→ Reader / OS Cache

相关新闻

2026大湾区EMBA含金量|中立择校测评与院校盘点

2026大湾区EMBA含金量|中立择校测评与院校盘点

民营企业家、企业创始人选EMBA,核心纠结点集中在排名含金量、课程是否适配转型、圈层是否精准、认证是否可用、投入性价比五大问题。本文从全球办学排名、院校办学定位、课程体系、学员圈层、产业资源五个客观维度,完成大湾区主流EMBA横向对比。全程无商…

2026/7/22 2:18:09阅读更多 →
PDM:Python依赖管理与项目构建的现代解决方案

PDM:Python依赖管理与项目构建的现代解决方案

1. PDM:现代Python开发者的瑞士军刀作为一个长期在Python生态中摸爬滚打的开发者,我深刻体会到依赖管理的重要性。传统工具如pip和virtualenv虽然能用,但面对现代Python项目的复杂需求时常常力不从心。直到遇到PDM——这个支持最新PEP标准的全…

2026/7/22 2:18:09阅读更多 →
腾讯通与勤哲Excel服务器集成实践

腾讯通与勤哲Excel服务器集成实践

1. 项目背景与需求解析腾讯通作为企业级即时通讯平台,与勤哲Excel服务器的集成需求主要来自两类典型场景:一是需要将审批流中的业务数据实时推送至通讯平台,二是需要将通讯平台中的指令转化为Excel服务器的自动化操作。这种集成打破了传统办公…

2026/7/22 2:16:09阅读更多 →
技术团队中的工具人:从问题定位到自动化解决方案

技术团队中的工具人:从问题定位到自动化解决方案

那天下午,我盯着屏幕上一行行日志,试图定位一个诡异的线上问题。问题本身不复杂,但定位过程像在开一把生锈的锁——你知道锁芯就在那里,但就是找不到那个恰到好处的角度和力道。团队里有人提议直接重启服务,有人建议加…

2026/7/22 4:26:28阅读更多 →
Java开发者转型C++实战指南:跨越思维鸿沟,掌握高性能编程

Java开发者转型C++实战指南:跨越思维鸿沟,掌握高性能编程

1. 转型动机与核心挑战:为什么是C,以及你需要跨越的鸿沟 最近几年,我身边从Java转向C的朋友和同事越来越多。这背后其实有个挺有意思的现象:一方面,Java生态依然庞大,岗位需求稳定;另一方面&…

2026/7/22 4:26:28阅读更多 →
VRChat OSC开源项目实战:从协议原理到故障排查全指南

VRChat OSC开源项目实战:从协议原理到故障排查全指南

1. 项目概述:当VRChat遇上OSC,开源社区的“连接”艺术如果你在VRChat社区里混迹过一段时间,或者热衷于折腾虚拟化身(Avatar)的交互,那你大概率听说过OSC(Open Sound Control)这个词。…

2026/7/22 4:26:28阅读更多 →
TI DSP EMIFA中断与NAND Flash ECC寄存器实战配置指南

TI DSP EMIFA中断与NAND Flash ECC寄存器实战配置指南

1. 项目概述与核心价值在嵌入式系统开发,尤其是基于德州仪器(TI)C6000系列DSP或类似高性能微控制器的项目中,外部存储器接口(EMIFA)和NAND Flash控制器是连接外部世界、扩展系统能力的关键桥梁。然而&#…

2026/7/22 4:26:28阅读更多 →
Windows下Python依赖编译:VS2017安装配置与实战指南

Windows下Python依赖编译:VS2017安装配置与实战指南

1. 项目概述:为什么需要Visual Studio Community 2017来编译Python依赖?如果你在Windows上鼓捣Python,尤其是涉及到需要编译原生扩展(C/C写的那些.pyd或.so文件)的库时,大概率会遇到一个让人头疼的报错&…

2026/7/22 4:26:28阅读更多 →
LangChain 零基础快速上手:从 Hello World 到智能文档问答助手

LangChain 零基础快速上手:从 Hello World 到智能文档问答助手

一、引言:大模型浪潮下的开发困境 随着 ChatGPT 的爆火,大模型(Large Language Model, LLM)已成为开发者工具箱中的新宠。然而,当我们兴奋地拿到 OpenAI API Key,准备大干一场时,却常常陷入这样…

2026/7/22 4:24:28阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 0:53:59阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 0:53:59阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 0:53:59阅读更多 →
中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业做小程序,最常见的矛盾是预算有限,但又不希望功能太单薄;没有技术团队,但又希望后续能自己运营;想快速上线,又担心隐性收费和售后失联。选型时如果只看“低价套餐”或“案例数量”,很容…

2026/7/22 0:01:17阅读更多 →
GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

企业做营销,最怕钱花完了,资产没有留下。 效果广告能带来一段时间的曝光,但预算停止后,流量往往也随之停止。短视频内容可能在几天内冲高,也可能很快沉下去。AI搜索时代,企业需要重新思考一个问题&#xff…

2026/7/22 0:01:17阅读更多 →
Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复 一、你的 Agent 在"再想想"的循环里绕了 12 轮,用户已经关窗口了 Agent 与人最大的区别是:人知道什么时候该停下来给答案,Agent 会一直"想"下去。你给 Agent 接…

2026/7/22 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/21 22:53:50阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/21 18:53:30阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/21 18:53:30阅读更多 →