Open1
NSEGで発表するduckdb紹介のプロット

duckdb紹介
トピック打っとかなきゃ誰にも見つからへんやろ作戦
- duckdb.org
- 祝1.0リリース
特徴
- インメモリ、組み込み、カラムナデータベース
- それ自体が静的ライブラリ
- データ分析のようなOLAPでの使用が主戦場
- 永続化も可能
- 主だったライバルは、Snowflake, ClickHouse
- いくつかの言語バインディングが標準で提供
- https://duckdb.org/docs/api/overview
- C/C++
- Rust
- JS/TS
- Python
- WASM
- 多彩な外部データ取り込み
- https://duckdb.org/docs/data/overview
- CSV
- JSON
- Apache Parquet
- PostgrSQL - Wired protocolで直結
- Writeも可能
- SQLite - 内部でAPI直呼びで直結
- 豊富な機能拡張
- Live DEMOも公式で提供
- https://duckdb.org/docs/
- WASM版
構文
-
PostgreDQLのパーザがベース
- 大体同じことができる
- 標準SQL
- データ型 - だいたいPostgreSQLと同じ
- https://duckdb.org/docs/sql/data_types/overview
- enum
- PostgreSQL式型キャスト(::)も使える
- CTE
- 式内materialization
- https://www.postgresql.jp/document/16/html/queries-with.html#QUERIES-WITH-CTE-MATERIALIZATION
- materializeの強制 or 解除
- CTE内で別のCTE使うケース
- DBエンジンが効かせてメモリにキャッシュする、レコード数に関係なく!
- キャッシュがファイルにパージされて遅くなる要因
- materialize解除で現実的な速度に改善できる
- 式内materialization
- lateral join
- 公式だと直積での説明しかなくて残念
- 相関サブクエリのJoinもちゃんとできるので安心
select * from t1 join lateral (...) t2 on true;
- Window関数
- Windowフレーム
- RowとRangeのみ
- https://duckdb.org/docs/sql/window_functions#framing
- 特にWindowフレームの説明がわかりやすいので一見の価値あり
- RowとRangeのみ
- Windowフレーム
- 大体同じことができる
-
独自拡張
- select
- JOIN拡張
- asof join
- 指定日以前の直近の日付の数値
- SnowflakeやClickHouseでも使える模様
- positional join
- 実体はfull outer join
- 欠損行はnullに
- zip演算を思い浮かべるとわかりやすいかも
- asof join
- ソートして配列型に詰め込む集約関数
- 配列・リスト型のラムダ式
- 配列、リストのunnest
- スター拡張
- https://duckdb.org/docs/sql/expressions/star
- columns
- 正規表現による列名のパターンマッチ
- ラムダ式
- create table t (yobi001 varchar, ..., yobi256 varchar);
- select columns( c -> substr(c, 5)::int between 10 and 20) from t;
- exclude
- 特定列だけ除外
select * exclude(foo) from t;
- replace
- 特定列だけ変更できる
- insert-selectで大活躍の予感
insert into t2 select * replace(id*100 as id) from t1;
- 特定列だけ変更できる
- CSV, JSON等をパス指定でそのままselectできる(拡張子がある場合のみ)
- https://duckdb.org/docs/data/json/overview
- WEBサーバーの先からの取得も
- globで一括指定することもできる
- from first syntax
- from + where or from + selectのみ
- from where selectはかけない残縁な子
from (select * from t where id > 5) select id;
select exists (from t where id > 5);
- ケツカンマのサポート
- order by でselect句の別名が指定できる
- JOIN拡張
- insert
- insert or replace
- なかったらinsertあったらupdate
- PostgreSQLのon conflict doも使えるがより直感的
- by name
- snsert select で、いちいち位置を合わせなくても良くて便利
- insert or replace
- select
-
独自Statement
- https://duckdb.org/docs/sql/statements/overview
- describe
- tableやselect結果の型を出力
- summarize
- select結果の最大値や最小値、null数等をレポート
- pivot
- sample
できなかったこと
-
alter tableで主キーの変更
- ctasでの致命的な致命傷
-
by nameでのinsert
- エイリアスを付与すると、エイリアス込みの列名を探そうとしてエラー
a.foo as foo
-
スカラ問い合わせ(サブクエリ)で複数行返す場合、先頭行返す
- エラーにして欲しかった・・・
select (select * from generate_series(1,10));
-
ネストしたderived tableで複数回、unnestするとデータが欠損(先頭行のみに)
-
JS/TSバインディング
- パラメータの値としてArrayやObjectを渡せない
- 渡せるのは、数値、文字列、boolean、nullのみ
- IN句やANY句に渡す場合は展開する必要あり
- CLIではできるのでバインディングの制限か?
- 名前付きパラメータが使えない(位置パラメータのみ)
- 順番変えたら地獄
- インポートAPI使ったら、文字列->enum自動変換してくれなかった(0.10.1の時)
- 今はしてくれるかも・・・(未確認)
- パラメータの値としてArrayやObjectを渡せない
DBメンテナンス
- JDBCが提供されてるので、DBeaverが使える
- https://duckdb.org/docs/guides/sql_editors/dbeaver