关于 ducklake
DuckLake 是一种湖仓格式,将 SQL 目录数据库与 Parquet 数据文件结合,面向管理湖仓数据的开发者。每次变更都会生成不可变快照,可用于时间旅行、变更馈送和冲突处理。
主要功能
- 01支持多种 SQL 目录
- 02数据存储于 Parquet 文件
- 03不可变快照与时间旅行
- 04元数据级架构变更
- 05支持分区与维护操作
适用场景
- 01通过快照查看历史数据
- 02调整表结构而不重写文件
- 03按时间或字段划分新数据
- 04清理过期快照及孤立文件
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ brojonat/ llmsrules --skill ducklake安装后在 Claude Code 中输入/ducklake确认已加载。
详细介绍
DuckLake
DuckLake 是一种开放式湖仓格式,采用 SQL 目录数据库(PostgreSQL、DuckDB、SQLite)和存储在任意后端(本地、S3、R2、GCS、Azure)上的 Parquet 数据文件。
每次变更都会创建不可变的快照,支持时间旅行、变更馈送和冲突解决。
安装与连接
INSTALL ducklake;
LOAD ducklake;
-- Local DuckDB catalog + local files
ATTACH 'ducklake:metadata.ducklake' AS my_lake;
-- PostgreSQL catalog + S3 storage
ATTACH 'ducklake:postgres:dbname=ducklake host=myhost' AS my_lake
(DATA_PATH 's3://my-bucket/data/');
-- Read-only / at specific snapshot
ATTACH 'ducklake:metadata.ducklake' AS my_lake (READ_ONLY);
ATTACH 'ducklake:metadata.ducklake' AS my_lake (SNAPSHOT_VERSION 3);
ATTACH 'ducklake:metadata.ducklake' AS my_lake (SNAPSHOT_TIME '2025-05-26 00:00:00');
核心操作
-- DDL
CREATE SCHEMA my_schema;
CREATE TABLE my_schema.tbl (id INTEGER NOT NULL, name VARCHAR, ts TIMESTAMP);
-- DML
INSERT INTO tbl VALUES (1, 'alice', now());
UPDATE tbl SET name = 'bob' WHERE id = 1;
DELETE FROM tbl WHERE id = 1;
-- Upsert via MERGE INTO (no primary keys in DuckLake)
MERGE INTO target USING source
ON target.id = source.id
WHEN MATCHED THEN UPDATE SET name = source.name
WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name);
架构演进
所有变更都只修改元数据(不会重写文件):
ALTER TABLE tbl ADD COLUMN new_col INTEGER;
ALTER TABLE tbl ADD COLUMN new_col VARCHAR DEFAULT 'hello';
ALTER TABLE tbl DROP COLUMN old_col;
ALTER TABLE tbl RENAME old_col TO new_name;
ALTER TABLE tbl ALTER col SET TYPE BIGINT; -- lossless promotions only
有效的类型提升:int8->int16/32/64、int16->int32/64、int32->int64、float32->float64。
快照与时间旅行
-- List / inspect snapshots
SELECT * FROM my_lake.snapshots();
FROM my_lake.current_snapshot();
-- Add metadata to a snapshot
BEGIN;
INSERT INTO tbl VALUES (1, 'data');
CALL my_lake.set_commit_message('author', 'Description', extra_info => '{"key": "value"}');
COMMIT;
-- Time travel
SELECT * FROM tbl AT (VERSION => 3);
SELECT * FROM tbl AT (TIMESTAMP => now() - INTERVAL '1 week');
-- Change feed between snapshots
FROM my_lake.table_changes('tbl', 2, 5);
FROM my_lake.table_changes('tbl', now() - INTERVAL '1 week', now());
分区
ALTER TABLE tbl SET PARTITIONED BY (region);
ALTER TABLE tbl SET PARTITIONED BY (year(ts), month(ts));
ALTER TABLE tbl RESET PARTITIONED BY;
函数:identity、year()、month()、day()、hour()。仅影响新数据。
维护
-- All-in-one
CHECKPOINT;
-- Individual operations
CALL ducklake_merge_adjacent_files('my_lake');
CALL ducklake_expire_snapshots('my_lake', older_than => now() - INTERVAL '1 week');
CALL ducklake_cleanup_old_files('my_lake', older_than => now() - INTERVAL '1 week');
CALL ducklake_delete_orphaned_files('my_lake', older_than => now() - INTERVAL '1 week');
CALL ducklake_rewrite_data_files('my_lake', 'tbl', delete_threshold => 0.5);
配置
-- Persistent settings (stored in catalog)
CALL my_lake.set_option('parquet_compression', 'zstd');
CALL my_lake.set_option('target_file_size', '256MB', table_name => 'big_table');
关键设置:parquet_compression(snappy/zstd/gzip)、target_file_size(512MB)、data_inlining_row_limit(0)、encrypted(false)、require_commit_message(false)。
与纯 DuckDB 的主要区别
- 不支持索引、主键、外键、唯一约束或检查约束
- 使用
MERGE INTO而非INSERT ... ON CONFLICT - 每个事务都会创建一个快照
- 架构变更只修改元数据
- 删除采用读时合并(删除文件,而非原地变更)
- 更新 = 在一个事务中执行 DELETE + INSERT
- 仅支持
NOT NULL约束
评论
支持 Markdown