mcpField
M
matlab-use-duckdb

matlab-use-duckdb

github.com/matlab数据与数据库1.2k84 次安装2 天前更新
代码仓库

关于 matlab-use-duckdb

matlab-use-duckdb 是指导 MATLAB 用户通过 Database Toolbox 使用 DuckDB 的技能,适用于文件分析和内存外预处理。它强调先评估数据与内存的比例,再将可用 SQL 表达的筛选、聚合等操作交给 DuckDB。

主要功能

  1. 01通过 Database Toolbox 连接 DuckDB
  2. 02使用 SQL 直接查询 CSV、Parquet 和 JSON
  3. 03对大型数据执行筛选与聚合
  4. 04创建或读取便携式 DuckDB 数据库
  5. 05根据数据规模选择 DuckDB 或 MATLAB 流程

适用场景

  1. 01用 SQL 分析大型 CSV 或 Parquet 文件
  2. 02在载入 MATLAB 前缩减数据量
  3. 03将整理后的文件数据持久化到数据库
  4. 04为开发工作流创建便携式分析数据库

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-use-duckdb

安装后在 Claude Code 中输入/matlab-use-duckdb确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

manifest.yaml
reference/
INDEX.md
reference/cards/
development-database.md
extensions.md
file-analytics.md
reduce-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 接口

加载时协议

当此技能加载到已有代码的会话中时:

  1. 审查数据管道——确定数据如何进入工作流:

    • 数据是否通过 MATLAB I/O(readtable、readmatrix、readcell、readtimetable、parquetread、xlsread、csvread)读取?
    • 查询前是否先通过 sqlwrite 将数据写入 DuckDB?
    • 如果是:这就是先加载再查询的反模式。DuckDB 很可能可以直接通过 read_csv、read_parquet 或 read_xlsx(excel 扩展)读取源文件。
  2. 根据决策框架评估每个数据源:

    • DuckDB 能否直接读取此文件类型?(CSV、Parquet、JSON,以及通过扩展读取 Excel)
    • 能否将筛选/聚合下推到 SQL 读取操作中?
    • MATLAB I/O 步骤是否构成性能瓶颈?
  3. 建议架构调整——审查范围不要局限于 API 是否正确。建议将 readtable/xlsread + sqlwrite + 查询链替换为 fetch(conn, "SELECT ... FROM read_csv/read_parquet/read_xlsx(...)")。

此技能中价值最高的模式是架构层面的:将文件分析下推可以消除整个管道阶段,并带来 10 倍以上的提速。

预检

在决定采用 DuckDB 方案前,估算文件大小与可用 RAM 的比例(同时考虑文件格式在内存中的膨胀),并据此选择处理路径:

条件处理路径原因
单个文件,比例 < 0.5MATLAB 原生 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') 确认。

问题:扩展安装失败

问题: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.


评论

支持 Markdown