mcpField
D
ducklake

ducklake

github.com/brojonat数据与数据库146 次安装2 周前更新
代码仓库

关于 ducklake

DuckLake 是一种湖仓格式,将 SQL 目录数据库与 Parquet 数据文件结合,面向管理湖仓数据的开发者。每次变更都会生成不可变快照,可用于时间旅行、变更馈送和冲突处理。

主要功能

  1. 01支持多种 SQL 目录
  2. 02数据存储于 Parquet 文件
  3. 03不可变快照与时间旅行
  4. 04元数据级架构变更
  5. 05支持分区与维护操作

适用场景

  1. 01通过快照查看历史数据
  2. 02调整表结构而不重写文件
  3. 03按时间或字段划分新数据
  4. 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