Chapter 01

DuckDB 简介与安装

理解 OLAP vs OLTP、列式存储原理、嵌入式数据库优势,以及多语言安装方式

1.1 OLTP vs OLAP:两种不同的数据库世界

数据库按工作负载可以分为两大类,它们的设计目标截然不同:

维度OLTP(联机事务处理)OLAP(联机分析处理)
全称On-Line Transaction ProcessingOn-Line Analytical Processing
典型操作INSERT / UPDATE / DELETE 单行SELECT 聚合大量行
数据量通常 MB ~ GBGB ~ TB 甚至 PB
查询特点简单点查,毫秒级响应复杂聚合,扫描大量列
存储方式行式存储(Row-oriented)列式存储(Column-oriented)
代表数据库MySQL、PostgreSQL、SQLiteDuckDB、ClickHouse、BigQuery、Snowflake
典型用途电商下单、用户登录、支付流水销售报表、用户行为分析、BI 看板
🦆

DuckDB 的定位 DuckDB 是一个嵌入式 OLAP 数据库。它专门针对分析查询(读多写少、大范围聚合)优化,而不是 OLTP(高频单行事务)。把它理解为"分析领域的 SQLite"非常贴切。

1.2 SQLite 的对比:行存 vs 列存

SQLite 是最著名的嵌入式数据库,DuckDB 在很多方面借鉴了 SQLite 的设计哲学(无服务进程、单文件),但在存储引擎上做了根本性的不同选择。

📦

行式存储(SQLite/MySQL) 一行数据的所有列存放在一起。读取某行很快,但分析查询(如 SUM(sales) 跨 100 万行)必须读取整行,浪费大量 I/O 在无关列上。

📊

列式存储(DuckDB/ClickHouse) 同一列的所有值连续存放。分析查询只需读取目标列,I/O 减少 10~100 倍;同列数据类型相同,压缩率极高(ZSTD/Snappy)。

直观示意:查询 SUM(amount)

假设有 100 万行订单数据,每行包含 order_id、user_id、product、amount、created_at 5 列:

存储方式需要读取的数据I/O 量速度
行式(MySQL)所有 5 列 × 100万行~500 MB
列式(DuckDB)仅 amount 列 × 100万行~8 MB(压缩后)极快

1.3 DuckDB 的核心优势

1.4 DuckDB 适用场景

📂

本地数据分析

直接查询本地 CSV/Parquet 文件,比 pandas 快 10-100 倍,比启动 Spark 集群方便 100 倍。

🔄

ETL / ELT 管道

构建本地数据转换管道,与 dbt 配合,无需云数仓也能完成复杂的数据转换工作。

🗃️

文件格式转换

CSV → Parquet、JSON → Parquet,一条 SQL 完成,自动推断 Schema,处理大文件毫无压力。

🔬

数据探索

在 Jupyter Notebook 中快速探索数据,ad-hoc 查询比 pandas 更直观、更快。

☁️

S3 文件直查

通过 httpfs 扩展,直接查询 S3/GCS/Azure Blob 上的文件,无需下载到本地。

🧪

数仓本地开发

用 dbt + DuckDB 在本地开发和测试数据模型,不花一分钱云费用,推送到生产再切换到 Snowflake/BigQuery。

⚠️

不适合的场景 DuckDB 不适合高并发 OLTP(高频单行写入)、多客户端并发写入(它是嵌入式数据库,写并发有限)、以及需要复杂行级权限控制的企业系统。这些场景请用 PostgreSQL 或 MySQL。

1.5 安装:多种方式任选

CLI(命令行工具)

BASH# macOS (Homebrew)
brew install duckdb

# 直接下载二进制(所有平台)
# 访问 https://duckdb.org/docs/installation/ 下载对应平台版本
# macOS Apple Silicon
curl -LO https://github.com/duckdb/duckdb/releases/latest/download/duckdb_cli-osx-universal.zip
unzip duckdb_cli-osx-universal.zip
./duckdb

# Linux
curl -LO https://github.com/duckdb/duckdb/releases/latest/download/duckdb_cli-linux-amd64.zip
unzip duckdb_cli-linux-amd64.zip
./duckdb

Python

BASH# Python 3.7+
pip install duckdb

# 或 uv(更快)
uv pip install duckdb

# 验证安装
python -c "import duckdb; print(duckdb.__version__)"

Node.js

BASH# npm
npm install duckdb

# 或更现代的 @duckdb/node-api
npm install @duckdb/node-api

R

R# R 控制台内安装
install.packages("duckdb")
library(duckdb)
con <- dbConnect(duckdb())
dbGetQuery(con, "SELECT 42")

Java / JVM

XML<!-- Maven -->
<dependency>
  <groupId>org.duckdb</groupId>
  <artifactId>duckdb_jdbc</artifactId>
  <version>1.1.3</version>
</dependency>

1.6 第一个查询:直接读 CSV 文件

DuckDB 最令人兴奋的特性之一:直接查询 CSV 文件,不需要先建表、不需要导入数据

准备测试数据

BASH# 创建一个示例 CSV 文件
cat > sales.csv <<EOF
date,region,product,amount
2024-01-01,华北,笔记本,8999
2024-01-01,华南,手机,3999
2024-01-02,华北,平板,4999
2024-01-02,华东,笔记本,8999
2024-01-03,华南,手机,3999
2024-01-03,华东,平板,4999
EOF

DuckDB CLI 中直接查询

SQL-- 启动 DuckDB CLI(不带参数=内存模式)
duckdb

-- 直接 SELECT CSV 文件!
SELECT * FROM 'sales.csv';

-- 按地区聚合销售额
SELECT
    region,
    SUM(amount) AS total_sales,
    COUNT(*) AS order_count
FROM 'sales.csv'
GROUP BY region
ORDER BY total_sales DESC;

Python 中使用

PYTHONimport duckdb

# 执行查询并获取结果(返回 list of tuples)
result = duckdb.sql("SELECT * FROM 'sales.csv'").fetchall()
print(result)

# 返回 pandas DataFrame
df = duckdb.sql("""
    SELECT region, SUM(amount) as total
    FROM 'sales.csv'
    GROUP BY region
    ORDER BY total DESC
""").df()
print(df)

1.7 名词解释:核心概念

💡

本章小结 DuckDB 是嵌入式 OLAP 数据库,无服务进程,像 SQLite 一样易部署,但专为分析查询优化。列式存储 + 向量化执行是其高性能的根本。适合本地数据分析、ETL、文件查询,不适合高并发 OLTP。一行 pip install duckdb 即可上手,可直接 SELECT CSV/Parquet 文件,与 pandas 深度集成。