关于 matlab-use-duckdb
matlab-use-duckdb 是指导 MATLAB 用户通过 Database Toolbox 使用 DuckDB 的技能,适用于文件分析和内存外预处理。它强调先评估数据与内存的比例,再将可用 SQL 表达的筛选、聚合等操作交给 DuckDB。
主要功能
- 01通过 Database Toolbox 连接 DuckDB
- 02使用 SQL 直接查询 CSV、Parquet 和 JSON
- 03对大型数据执行筛选与聚合
- 04创建或读取便携式 DuckDB 数据库
- 05根据数据规模选择 DuckDB 或 MATLAB 流程
适用场景
- 01用 SQL 分析大型 CSV 或 Parquet 文件
- 02在载入 MATLAB 前缩减数据量
- 03将整理后的文件数据持久化到数据库
- 04为开发工作流创建便携式分析数据库
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-use-duckdb安装后在 Claude Code 中输入/matlab-use-duckdb确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreference/INDEX.mdreference/cards/development-database.mdextensions.mdfile-analytics.mdreduce-large-data.md详细介绍
MATLAB Database Toolbox 与 DuckDB 的接口
使用 Database Toolbox 从 MATLAB 处理 DuckDB 数据库。DuckDB 是一款嵌入式分析型数据库引擎,自 R2026a 起随 Database Toolbox 一同提供。它支持基于 SQL 的文件分析、超内存数据预处理和便携式开发数据库,无需配置外部数据库服务器。
何时使用此技能
- 连接到 DuckDB 数据库(内存中或基于文件)
- 为开发工作流创建新的 DuckDB 数据库文件
- 直接使用 SQL 查询 CSV、Parquet 或 JSON 文件
- 在分析前缩减或分析大型数据
- 将 DuckDB 用作非数学运算引擎(筛选、聚合、去重、字符串清理、类型转换、排序、抽样)
- 安装和使用 DuckDB 扩展
- 将文件数据持久化到
.duckdb文件中,以便重复查询 - 用户提及以下关键词:DuckDB、duckdb()、分析引擎、嵌入式数据库、大型 CSV、大型 Parquet/JSON、文件过大而无法使用 readtable、在数据源处筛选/聚合、去重、分析前缩减、分析大型文件、持久化文件导入、对 CSV 执行 SQL、对 Parquet 执行 SQL、对 JSON 执行 SQL、使用 SQL 查询 CSV、使用 SQL 查询 Parquet、对文件运行 SQL、对文件执行 SQL 查询、直接查询文件、无需数据库的 SQL、进程内 SQL
何时不使用
- 适合放入内存的单个文件——使用 MATLAB 原生 I/O(
readtable/readmatrix) - 多文件工作流——优先使用
datastore/tall;DuckDB glob 是备用方案,而非默认方案 - 数据超出内存容量,且无法通过 SQL 缩减至可处理范围——使用
datastore/tall进行流式处理 - 计算密集或数值敏感的操作(归一化、窗口统计、异常值检测)——缩减数据后交由 MATLAB 处理
- 连接到 MySQL、PostgreSQL、SQLite 或其他外部数据库——使用其原生接口或 JDBC/ODBC
- 对象关系映射——使用 ORM(通过
Mappable类配合ormread/ormwrite) - MongoDB、Cassandra 或 Neo4j——使用其专用 Database Toolbox 接口
加载时协议
当此技能加载到已有代码的会话中时:
-
审查数据管道——确定数据如何进入工作流:
- 数据是否通过 MATLAB I/O(
readtable、readmatrix、readcell、readtimetable、parquetread、xlsread、csvread)读取? - 查询前是否先通过
sqlwrite将数据写入 DuckDB? - 如果是:这就是先加载再查询的反模式。DuckDB 很可能可以直接通过
read_csv、read_parquet或read_xlsx(excel 扩展)读取源文件。
- 数据是否通过 MATLAB I/O(
-
根据决策框架评估每个数据源:
- DuckDB 能否直接读取此文件类型?(CSV、Parquet、JSON,以及通过扩展读取 Excel)
- 能否将筛选/聚合下推到 SQL 读取操作中?
- MATLAB I/O 步骤是否构成性能瓶颈?
-
建议架构调整——审查范围不要局限于 API 是否正确。建议将
readtable/xlsread+sqlwrite+ 查询链替换为fetch(conn, "SELECT ... FROM read_csv/read_parquet/read_xlsx(...)")。
此技能中价值最高的模式是架构层面的:将文件分析下推可以消除整个管道阶段,并带来 10 倍以上的提速。
预检
在决定采用 DuckDB 方案前,估算文件大小与可用 RAM 的比例(同时考虑文件格式在内存中的膨胀),并据此选择处理路径:
| 条件 | 处理路径 | 原因 |
|---|---|---|
| 单个文件,比例 < 0.5 | MATLAB 原生 I/O | 可放入内存;DuckDB 会带来不必要的复杂性 |
| 多个文件,或逐个文件处理 | datastore/tall(备用方案:DuckDB glob) | 流式处理是多文件场景的主要模式 |
| 单个文件,比例 ≥ 0.5,且可通过 SQL 表达缩减操作 | DuckDB:分析 → 操作 → 关闭 | 适合使用 DuckDB |
| 单个文件,比例 ≥ 0.5,且不适用 SQL 缩减 | datastore/tall | 无法缩减就没有使用 DuckDB 的优势 |
操作菜单
在 DuckDB SQL 中执行
| 操作 | SQL 示例 |
|---|---|
| 筛选行 | WHERE status = 'active' |
| 聚合 | GROUP BY region、SUM(revenue)、COUNT(*)、AVG(price) |
| 去重 | SELECT DISTINCT ... 或 ROW_NUMBER() OVER (PARTITION BY ...) |
| 字符串清理 | TRIM()、LOWER()、REPLACE()、REGEXP_REPLACE() |
| 类型转换 | TRY_CAST(col AS DATE)、CAST(col AS DOUBLE) |
| 排序 | ORDER BY timestamp |
| 抽样 | USING SAMPLE 10000 或 TABLESAMPLE RESERVOIR(10%) |
| 画像分析 | COUNT(*)、MIN/MAX、APPROX_COUNT_DISTINCT |
| 限制行数 | LIMIT 50000 |
不要在 DuckDB SQL 中执行
| 操作 | 原因 |
|---|---|
| 归一化 / z-score | 需要总体数据背景 |
| 窗口统计(移动平均、累积和) | 语义脆弱,NULL 处理方式不同 |
| 异常值检测 | 需要统计判断 |
| 插值 / 重采样 | 依赖领域特定逻辑 |
| 信号处理 | 不属于 SQL 的应用领域 |
| 机器学习特征 | 取决于模型 |
SQL 操作的语义并不总是与 MATLAB 一致(NULL 处理、排序顺序、去重)。已知的不一致之处请参见 reference/cards/reduce-large-data.md。
数据缩减工作流
如果预检检查将任务路由到 DuckDB,请遵循 reference/cards/reduce-large-data.md 中的「分析 → 操作 → 关闭」模式。
DuckDB 会筛选、重塑、清理和缩减数据。数据适合放入内存且连接关闭后,DuckDB 的工作就完成了。
什么是 DuckDB?为什么 Database Toolbox 会附带它?
DuckDB 是一种嵌入式、无服务器分析型数据库引擎。与 MySQL 或 PostgreSQL 不同,它无需服务器和配置,可在 MATLAB 进程内运行。
随 Database Toolbox 附带的原因(R2026a+):
- 零配置数据库 — 执行
conn = duckdb()即可立即获得完整的 SQL 引擎。 - 面向文件的分析引擎 — 无需将 CSV、Parquet 和 JSON 文件载入内存,即可直接使用 SQL 查询。
- 内存外预处理 — 筛选、聚合、联接和排序大于内存容量的数据集,然后只将结果载入 MATLAB。
- 便携式开发数据库 —
.duckdb或.db文件可在任何安装了 Database Toolbox 的机器上使用。无需设置数据库。 - AI Agent 的优势 — Agent 的 SQL 知识可直接用于构建强大的分析查询。
DuckDB 不会取代 MATLAB 的文件 I/O(readtable 等)或 datastore/tall。当数据超出内存容量,且任务可归纳为 SQL 能表达的操作时,DuckDB 是一种高性能替代方案。如果不适用数据缩减,datastore/tall 仍是正确的处理方式。
关键规则
预检关卡
- 务必在编写任何 DuckDB 代码之前执行预检中的数据量与 RAM 比率检查。如果比率 < 0.5,请停止并改用 MATLAB 原生 I/O。不要继续使用 DuckDB 模式。
连接
- 连接时务必使用
duckdb(),不要使用database()、JDBC 或 ODBC。 - 务必使用
isopen(conn)验证,并使用close(conn)关闭连接。
API 范围
- 所有标准函数均可使用:
sqlread、fetch、execute、sqlwrite、sqlfind、sqlinnerjoin、sqlouterjoin、commit、rollback。 - DuckDB 不支持
databasePreparedStatement。请改用execute或sqlwrite。 - 从数据库表读取时(使用
sqlread),通过databaseImportOptions使用ExcludeDuplicates。直接查询文件时(通过fetch使用read_csv/read_parquet),请在 SQL 中使用SELECT DISTINCT。
命名表与文件查询
- 对命名数据库表进行简单行筛选时,务必使用带
RowFilter的sqlread,不要使用带 WHERE 的fetch。创建rowfilter对象,并通过RowFilter名称-值参数传入。 - 对命名表执行聚合、联接或复杂查询时,请使用带 SQL 的
fetch。 - 查询文件时务必使用
fetch(而非sqlread),因为查询需要SELECT * FROM read_csv('file.csv')这类 SQL 语法。 - 在 SQL 中指定文件路径时,务必使用单引号:
read_csv('data.csv')。
连接模式
| 目标 | 连接方式 | 原因 |
|---|---|---|
| 对文件进行分析查询 | duckdb() | 无需持久化;直接查询文件 |
| 临时工作区 | duckdb() | 速度快,关闭时会丢弃 |
| 可移植的开发数据库 | duckdb("mydata.duckdb") | 创建 .duckdb 或 .db 文件;可在任何机器上使用 |
| 打开现有数据库 | duckdb("existing.db") | 对现有 .db 或 .duckdb 文件进行读写 |
| 只读共享数据库 | duckdb("shared.duckdb", ReadOnly=true) | 防止意外写入 |
常见模式
模式 1:用于文件的分析引擎
conn = duckdb();
result = fetch(conn, "SELECT region, SUM(revenue) as total " + ...
"FROM read_parquet('sales.parquet') " + ...
"GROUP BY region ORDER BY total DESC");
close(conn);
模式 2:内存不足时的预处理
conn = duckdb();
summary = fetch(conn, "SELECT date, AVG(value) as avg_val " + ...
"FROM read_csv('huge_dataset.csv') " + ...
"WHERE status = 'valid' " + ...
"GROUP BY date ORDER BY date");
close(conn);
% summary fits in memory — continue with MATLAB analysis
模式 3:使用 RowFilter 读取指定表
conn = duckdb("inventory.duckdb", ReadOnly=true);
rf = rowfilter("quantity");
data = sqlread(conn, "products", RowFilter=rf.quantity < 10);
close(conn);
模式 4:开发数据库
conn = duckdb("dev.duckdb");
sqlwrite(conn, "experiments", experimentData);
rf = rowfilter("score");
results = sqlread(conn, "experiments", RowFilter=rf.score > 0.8);
close(conn);
模式 5:使用 Glob 查询多个文件
当 datastore/tall 不适用时使用(例如,对多个文件进行 SQL 聚合)。对于按文件顺序逐一处理的情况,优先使用 datastore。
conn = duckdb();
data = fetch(conn, "SELECT * FROM read_parquet('data/year=2024/*.parquet') " + ...
"WHERE category = 'A'");
close(conn);
模式 6:扩展
conn = duckdb();
execute(conn, "INSTALL httpfs");
execute(conn, "LOAD httpfs");
data = fetch(conn, "SELECT * FROM read_parquet('https://example.com/data.parquet') LIMIT 1000");
close(conn);
对于 Excel 文件,使用 excel 扩展和 read_xlsx(不要使用 spatial 中的 st_read):
conn = duckdb();
execute(conn, "INSTALL excel");
execute(conn, "LOAD excel");
data = fetch(conn, "SELECT * FROM read_xlsx('report.xlsx')");
close(conn);
模式 7:从文件进行持久化导入
conn = duckdb("analytics.duckdb");
execute(conn, "CREATE TABLE events AS SELECT * FROM read_parquet('raw_events.parquet')");
% Future sessions: query by table name (no file re-read)
result = sqlread(conn, "events");
close(conn);
有关详细示例,请参阅:
- 文件分析和内存不足时的预处理:
reference/cards/file-analytics.md - 开发数据库工作流:
reference/cards/development-database.md - DuckDB 扩展:
reference/cards/extensions.md
常见错误
% WRONG — using database() or JDBC to connect to DuckDB
conn = database("", "", "", "org.duckdb.DuckDBDriver", "jdbc:duckdb:");
% CORRECT
conn = duckdb();
% WRONG — using sqlread for file queries (expects a table name)
data = sqlread(conn, "read_csv('data.csv')");
% CORRECT — use fetch with SQL
data = fetch(conn, "SELECT * FROM read_csv('data.csv')");
% WRONG — double quotes for file paths in SQL
data = fetch(conn, "SELECT * FROM read_csv(""data.csv"")");
% CORRECT — single quotes
data = fetch(conn, "SELECT * FROM read_csv('data.csv')");
% WRONG — loading huge file into MATLAB then filtering
data = readtable("huge.parquet"); filtered = data(data.val > 100, :);
% CORRECT — let DuckDB filter on disk
conn = duckdb();
filtered = fetch(conn, "SELECT * FROM read_parquet('huge.parquet') WHERE val > 100");
close(conn);
% WRONG — using databasePreparedStatement (not supported)
pstmt = databasePreparedStatement(conn, "INSERT INTO t VALUES(?, ?)");
% CORRECT — use sqlwrite
sqlwrite(conn, "t", data);
% WRONG — using st_read from spatial extension for Excel files
data = fetch(conn, "SELECT * FROM st_read('file.xlsx')");
% CORRECT — use excel extension with read_xlsx
execute(conn, "INSTALL excel");
execute(conn, "LOAD excel");
data = fetch(conn, "SELECT * FROM read_xlsx('file.xlsx')");
% WRONG — MATLAB table column named with SQL reserved keyword
data = table(1, "A", 'VariableNames', {'id','group'});
sqlwrite(conn, "t", data); % Parser error: "group" is reserved
% CORRECT — rename column before writing
data = renamevars(data, 'group', 'experiment_group');
sqlwrite(conn, "t", data);
检查清单
完成 DuckDB 代码前,请确认:
- 管道检查:DuckDB 可以直接读取文件时,不要使用不必要的 MATLAB 文件 I/O(例如,
readtable、xlsread、parquetread)+sqlwrite链式操作 - 使用
duckdb()或duckdb("file.duckdb")/duckdb("file.db")进行连接,而不是database()或 JDBC - 连接后检查
isopen(conn) - 文件查询使用带 SQL 的
fetch(而不是sqlread) - SQL 中的文件路径使用单引号
- 在将内存不足的数据导入 MATLAB 前,先在 DuckDB 中进行预处理
- 不使用
databasePreparedStatement(不受支持) - 操作完成后调用
close(conn)
故障排除
问题:找不到 duckdb 函数
- 解决方案:需要 R2026a+ 和 Database Toolbox。使用
ver('database')检查。
问题:使用文件查询时 sqlread 报错
- 解决方案:使用
fetch(conn, "SELECT * FROM read_csv('file.csv')")—sqlread只接受表名。
问题:ReadOnly 连接被拒绝访问
- 解决方案:不使用
ReadOnly重新连接:conn = duckdb("file.duckdb")。
问题:查询大型文件时内存不足
- 解决方案:在 SQL 中添加
WHERE、GROUP BY、LIMIT或聚合,以便在结果进入 MATLAB 前缩减结果大小。
问题:在 read_csv/read_parquet 中找不到文件路径
- 解决方案:路径相对于
pwd。使用绝对路径,或通过dir('file.csv')确认。
问题:扩展安装失败
- 解决方案:首次安装需要联网(之后会缓存)。请参阅 https://duckdb.org/docs/current/core_extensions/overview。
问题:sqlwrite 因列名出现“syntax error at or near”而失败
- 解决方案:列名是 SQL 保留关键字(
group、order、select、table等)。写入前使用renamevars(data, 'group', 'experiment_group')重命名。
问题:sqlwrite 类型不匹配
- 解决方案:DuckDB 支持丰富的数据类型(ARRAY、LIST、STRUCT、MAP)。使用
sqlfind(conn, "tableName")检查列类型。
版权所有 2026 The MathWorks, Inc.