DuckDB直接连接MySQL,以后还需要ETL吗?

如果你对 DuckDB 的印象还停留在本地分析、CSV 文件查询、Parquet 处理神器、Pandas 替代工具等,那么是时候了解一下这款官方 MySQL 扩展插件了。

DuckDB 提供的 MySQL 扩展插件可以让它把 MySQL 服务器当成一个可挂载的外部数据库,连接之后可以像访问本地 DuckDB 数据表一样访问 MySQL 中的数据,同时还支持写回 MySQL。

应用场景

  • 实时数据分析:传统架构需要将业务系统数据库(例如MySQL)通过 ETL 同步到数据仓库中进行数据分析,DuckDB 则可以通过插件直接读取 MySQL 数据进行实时分析。
  • 轻量级 ETL 数据管道:许多企业需要将数据库同步到数据湖中,DuckDB 通过一个命令就可以完成从 MySQL 到 Parquet 数据湖转换。
  • 数据库迁移:DuckDB 可以作为中间组件实现 MySQL 到 MySQL 的数据迁移,以及 MySQL 到 PostgreSQL 等的数据迁移。
  • 轻量级数据平台:很多中小公司没有数仓团队,无法支持 ClickHouse 这种大型平台;使用 MySQL + DuckDB + Metabase 这种轻量级报表分析系统维护成本极低。

安装加载

使用 INSTALL 语句安装 MySQL 插件的命令如下:

sql 复制代码
INSTALL mysql

首次使用时,系统会自动加载插件,或者也可以手动加载:

sql 复制代码
LOAD mysql;

连接 MySQL

DuckDB 提供了 ATTACH 命令,用于加载外部数据库连接。例如:

sql 复制代码
ATTACH 'host=localhost port=3306 database=dbname user=root password=xxxxxx' AS mysqldb (TYPE mysql);

USE mysqldb;

其中的连接参数需要替换为真实数据,这样 MySQL 数据库就被挂载到 DuckDB 中了。

除了以上参数之外,还可以指定 SSL 安全连接以及连接池配置。

为了不在 SQL 中暴露密码,推荐使用 DuckDB 密钥(Secret)管理器。例如:

sql 复制代码
-- 创建密钥
CREATE SECRET (
    TYPE mysql,
    HOST '127.0.0.1',
    PORT 3306,
    DATABASE dbname,
    USER 'root',
    PASSWORD 'XXXXXX'
);

-- 挂载数据库
ATTACH '' AS mysqldb (TYPE mysql);

DuckDB 还支持密钥的持久化存储,同时也可以通过命名密钥管理多个 MySQL 实例。

读取 MySQL

连接到 MySQL 实例之后,可以像普通 DuckDB 数据表一样查询 MySQL 中的数据。例如:

sql 复制代码
SELECT customer_id, first_name,last_name
FROM mysqldb.sakila.customer LIMIT 3;

┌─────────────┬────────────┬───────────┐
│ customer_id │ first_name │ last_name │
│   uint16    │  varchar   │  varchar  │
├─────────────┼────────────┼───────────┤
│           1 │ MARY       │ SMITH     │
│           2 │ PATRICIA   │ JOHNSON   │
│           3 │ LINDA      │ WILLIAMS  │
└─────────────┴────────────┴───────────┘

如果想要将 MySQL 数据复制到 DuckDB 表中,同样非常简单:

sql 复制代码
CREATE TABLE local_customer AS
FROM mysqldb.sakila.customer;

SELECT COUNT(*) FROM local_customer;

┌──────────────┐
│ count_star() │
│    int64     │
├──────────────┤
│          599 │
└──────────────┘

写入 MySQL

DuckDB 不仅可以通过插件读取 MySQL 中的数据,同样也可以将数据写入 MySQL 数据库。例如:

sql 复制代码
-- 远程创建 MYSQL 数据表
CREATE TABLE mysqldb.t1(id INTEGER, name VARCHAR);

-- 写入数据
INSERT INTO mysqldb.t1 VALUES (42, 'DuckDB');

SELECT * FROM mysqldb.t1;

┌───────┬─────────┐
│  id   │  name   │
│ int32 │ varchar │
├───────┼─────────┤
│    42 │ DuckDB  │
└───────┴─────────┘

我们不仅可以写入 MySQL 数据,还可以执行 DDL 语句以及其他数据修改操作;如果担心误操作可能对 MySQL 数据库的影响,可以在 ATTACH 命令中使用只读参数。例如:

sql 复制代码
ATTACH '' AS mysqldb (TYPE mysql, READ_ONLY);

此时,我们只能执行数据查询,不能执行其他修改操作。

MySQL 插件还支持事务处理语句,例如 BEGIN、COMMIT、ROLLBACK。

数据交换

除了实时查询 MySQL 数据或者将其复制到 DuckDB 数据表中,我们还可以进一步将 DuckDB 作为轻量级 ETL 引擎,实现数据管道功能。例如:

sql 复制代码
-- MySQL 数据导出 Parquet 文件
COPY mysqldb.orders
TO 'orders.parquet';

-- Parquet 文件导入 MySQL
COPY mysqldb.orders
FROM 'orders.parquet';

原生 MySQL 语句

MySQL 插件还提供了两个函数,用于在远程数据库中执行 SQL 命令,支持 MySQL 专有语法。

mysql_query 表函数用于执行一个查询语句并返回结果,例如:

sql 复制代码
-- 查询 MySQL 版本
SELECT * FROM mysql_query(
    'mysqldb',
    'SELECT version();'
);

┌───────────┐
│ version() │
│  varchar  │
├───────────┤
│ 8.4.8     │
└───────────┘

mysql_execute 函数用于执行任意 MySQL 命令,包括 DDL 以及 DML。例如:

sql 复制代码
-- 创建远程 MySQL 数据表
CALL mysql_execute('mysqldb', 'CREATE TABLE my_table (i INTEGER)');

总结

MySQL 扩展插件实现了 DuckDB 远程访问 MySQL 数据库的功能,使得 DuckDB 正在从一个嵌入式分析型数据库逐渐进化成一个联邦数据查询平台。

参考文档:

https://duckdb.org/docs/current/core_extensions/mysql

相关推荐
2501_933670792 小时前
金融工程转数据分析通关指南
数据分析
Database_Cool_12 小时前
OLTP 和 OLAP 区别详解:分析型数据库和事务型数据库怎么选(附阿里云 AnalyticDB MySQL 选型指南)
数据库·mysql·阿里云
Database_Cool_12 小时前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移
数据库·分布式·mysql
姜太小白13 小时前
【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南
数据库·mysql
liuxiaowei314 小时前
【绝版教程】新版MySQL DBA高级实战进阶班 MySQL8.0 姜承尧-腾讯数据库总监
数据库·mysql·dba
临床数据科学和人工智能兴趣组17 小时前
RStudio的Console(控制台)是一个非常重要的组件
人工智能·机器学习·数据分析·r语言·r语言-4.2.1
sg_knight17 小时前
MySQL 存储过程详解:从入门到实战
android·数据库·mysql·database·dba·关系型数据库·db
Database_Cool_19 小时前
企业级多模态分析计算引擎选型:首选 AnalyticDB MySQL 向量 + SQL + 实时一体化方案
数据库·sql·mysql
暖和_白开水19 小时前
数据分析agent (七):contextvars 模块上下文request_id
java·前端·数据分析
宇宙第一小趴菜20 小时前
五、Oracle vs MySQL 架构深度对比笔记
mysql·oracle·架构