MySQL ShellでダンプしたファイルをDuckDBで読み取る

# TL;DR
MySQL Shellユーティリティの1つである[インスタンスダンプユーティリティ等](https://dev.mysql.com/doc/mysql-shell/8.0/ja/mysql-shell-utilities-dump-instance-schema.html)ですが、この機能を使って出力したファイルはDuckDBで読めるよという話です。

# テストデータの作成
まず、公式のsakilaデータセットをMySQLにロードし、MySQL Shellの `util.dumpSchemas()` でダンプします。コマンドラインだと以下のコマンドで実行できます。

```bash
$ mysqlsh <user>@<host> -- util dump-schemas sakila --outputUrl=./dump_sakila
```

出力したファイルは以下のようになっています。

```bash
$ ls | head
@.done.json
@.json
@.post.sql
sakila@actor@@0.tsv.zst
sakila@actor@@0.tsv.zst.idx
sakila@actor_info.pre.sql
sakila@actor_info.sql
sakila@actor.json
sakila@actor.sql
sakila@address@@0.tsv.zst
```

このうち `sakila@hogehoge@@0.tsv.zst` などとなっているものに `hogehoge` テーブルの実データがzstd圧縮されたtsv形式で出力されています。

# DuckDBでの読み取り
次に、これらのファイルをDuckDBで実際に読み取ってみます。
DuckDBのコンソールを開き、以下のように読み取るファイルのパスを指定する形でSELECT文を入力、実行します。

```SQL
D SELECT * FROM '/path/to/dump_sakila/sakila@actor@@*.tsv.zst';
```

DuckDBはgzipやzstdで圧縮されたファイルをそのまま読み出せるため、展開処理は不要です。また、ファイル名の指定部分にはワイルドカード `*` が使用可能です。今回は単一ファイルのため特に関係ありませんが、ダンプユーティリティでは大きなテーブルをダンプした時、複数のファイルに分割されて出力されます。その場合に全てのファイルを読み取るといったことが可能になります。

出力結果は以下のようになります。

```SQL
D SELECT * FROM '/path/to/dump_sakila/sakila@actor@@*.tsv.zst';
┌─────────┬───────────┬──────────────┬─────────────────────┐
│ column0 │  column1  │   column2    │       column3       │
│  int64  │  varchar  │   varchar    │      timestamp      │
├─────────┼───────────┼──────────────┼─────────────────────┤
│       1 │ PENELOPE  │ GUINESS      │ 2006-02-14 19:34:33 │
│       2 │ NICK      │ WAHLBERG     │ 2006-02-14 19:34:33 │
│       3 │ ED        │ CHASE        │ 2006-02-14 19:34:33 │
│       4 │ JENNIFER  │ DAVIS        │ 2006-02-14 19:34:33 │
│       5 │ JOHNNY    │ LOLLOBRIGIDA │ 2006-02-14 19:34:33 │
│       6 │ BETTE     │ NICHOLSON    │ 2006-02-14 19:34:33 │
│       7 │ GRACE     │ MOSTEL       │ 2006-02-14 19:34:33 │
│       8 │ MATTHEW   │ JOHANSSON    │ 2006-02-14 19:34:33 │
│       9 │ JOE       │ SWANK        │ 2006-02-14 19:34:33 │
│      10 │ CHRISTIAN │ GABLE        │ 2006-02-14 19:34:33 │
│      11 │ ZERO      │ CAGE         │ 2006-02-14 19:34:33 │
│      12 │ KARL      │ BERRY        │ 2006-02-14 19:34:33 │
│      13 │ UMA       │ WOOD         │ 2006-02-14 19:34:33 │
│      14 │ VIVIEN    │ BERGEN       │ 2006-02-14 19:34:33 │
│      15 │ CUBA      │ OLIVIER      │ 2006-02-14 19:34:33 │
│      16 │ FRED      │ COSTNER      │ 2006-02-14 19:34:33 │
│      17 │ HELEN     │ VOIGHT       │ 2006-02-14 19:34:33 │
│      18 │ DAN       │ TORN         │ 2006-02-14 19:34:33 │
│      19 │ BOB       │ FAWCETT      │ 2006-02-14 19:34:33 │
│      20 │ LUCILLE   │ TRACY        │ 2006-02-14 19:34:33 │
│       · │    ·      │   ·          │          ·          │
│       · │    ·      │   ·          │          ·          │
│       · │    ·      │   ·          │          ·          │
│     181 │ MATTHEW   │ CARREY       │ 2006-02-14 19:34:33 │
│     182 │ DEBBIE    │ AKROYD       │ 2006-02-14 19:34:33 │
│     183 │ RUSSELL   │ CLOSE        │ 2006-02-14 19:34:33 │
│     184 │ HUMPHREY  │ GARLAND      │ 2006-02-14 19:34:33 │
│     185 │ MICHAEL   │ BOLGER       │ 2006-02-14 19:34:33 │
│     186 │ JULIA     │ ZELLWEGER    │ 2006-02-14 19:34:33 │
│     187 │ RENEE     │ BALL         │ 2006-02-14 19:34:33 │
│     188 │ ROCK      │ DUKAKIS      │ 2006-02-14 19:34:33 │
│     189 │ CUBA      │ BIRCH        │ 2006-02-14 19:34:33 │
│     190 │ AUDREY    │ BAILEY       │ 2006-02-14 19:34:33 │
│     191 │ GREGORY   │ GOODING      │ 2006-02-14 19:34:33 │
│     192 │ JOHN      │ SUVARI       │ 2006-02-14 19:34:33 │
│     193 │ BURT      │ TEMPLE       │ 2006-02-14 19:34:33 │
│     194 │ MERYL     │ ALLEN        │ 2006-02-14 19:34:33 │
│     195 │ JAYNE     │ SILVERSTONE  │ 2006-02-14 19:34:33 │
│     196 │ BELA      │ WALKEN       │ 2006-02-14 19:34:33 │
│     197 │ REESE     │ WEST         │ 2006-02-14 19:34:33 │
│     198 │ MARY      │ KEITEL       │ 2006-02-14 19:34:33 │
│     199 │ JULIA     │ FAWCETT      │ 2006-02-14 19:34:33 │
│     200 │ THORA     │ TEMPLE       │ 2006-02-14 19:34:33 │
├─────────┴───────────┴──────────────┴─────────────────────┤
│ 200 rows (40 shown)                            4 columns │
└──────────────────────────────────────────────────────────┘
```

カラム名はtsvファイルに記録されていないため、仮の名称とデータ型のみが出力される形になります。この部分はどうしても補完が必要になりますね。
また、デフォルトでは最初の20行と最後の20行のみが返ってくるようになっています。これは[ドットコマンド](https://duckdb.org/docs/api/cli/dot_commands.html)の `.maxrows x` を入力することで `x` 行が返ってくるように変更することができます。

WHERE句やLIMIT句での結果絞り込みも可能です。

```SQL
D SELECT * FROM '/path/to/dump_sakila/sakila@actor@@*.tsv.zst' WHERE column1 LIKE 'B%' LIMIT 5;
┌─────────┬─────────┬───────────┬─────────────────────┐
│ column0 │ column1 │  column2  │       column3       │
│  int64  │ varchar │  varchar  │      timestamp      │
├─────────┼─────────┼───────────┼─────────────────────┤
│       6 │ BETTE   │ NICHOLSON │ 2006-02-14 19:34:33 │
│      19 │ BOB     │ FAWCETT   │ 2006-02-14 19:34:33 │
│      36 │ BURT    │ DUKAKIS   │ 2006-02-14 19:34:33 │
│      75 │ BURT    │ POSEY     │ 2006-02-14 19:34:33 │
│      83 │ BEN     │ WILLIS    │ 2006-02-14 19:34:33 │
└─────────┴─────────┴───────────┴─────────────────────┘
```

# 終わりに
ダンプユーティリティでバックアップを取得している場合に、ちょっと中身を確認してみたいケースがあればこの小技が役に立つかもしれません。