nato243 weblog.n-jitter brand iconweblog.n-jitter
テクノロジー

GoでDuckDBつかってみた

2025.05.24
Golang
GoでDuckDBつかってみた アイキャッチ

DuckDBが話題なのでGolangで素振りしておく

最近、分析系のデータベースとしてDuckDBがよく話題に上がる。

SQLiteのように組み込み型でありながら、分析クエリに特化した設計になっているらしい。

PostgreSQLやMySQLのような重厚なデータベースサーバーを立てるほどでもないが、SQLiteでは分析処理が重い、という中間的な用途にちょうど良さそう。バッチ処理と洗い替えで作る個人別レポートやレシート系とか実はいいんじゃないかしら。

Goでの開発が多いので、今回はGolangからDuckDBを使ってみる素振りをしておこう。

macでDuckDB install

まずはDuckDB CLIをインストールする。

# Homebrewでインストール

brew install duckdb

# バージョン確認
duckdb --version

これでCLIツールが使えるようになった。

MySQL CLIのような感覚で使える。


# 新しいデータベースファイルを作成して接続
duckdb sample.duckdb

テーブル作る

DuckDB CLIで基本的なテーブルを作成してみる。

-- ユーザーテーブル
CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name VARCHAR(100),
    age INTEGER,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 商品テーブル(配列カラムも含む)
CREATE TABLE products (
    id INTEGER PRIMARY KEY,
    name VARCHAR(100),
    price DECIMAL(10,2),
    category VARCHAR(50),
    tags VARCHAR[],  -- 配列型
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

初期データも入れておく。

-- ユーザーデータ
INSERT INTO users (id, name, age) VALUES 
(1, '田中太郎', 25),
(2, '佐藤花子', 32),
(3, '鈴木一郎', 28);

-- 商品データ(配列も含む)
INSERT INTO products (id, name, price, category, tags) VALUES 
(1, 'ノートPC', 89800.00, 'Electronics', ['Computer', 'Laptop', 'Work']),
(2, 'コーヒー豆', 1200.00, 'Food', ['Coffee', 'Beverage', 'Premium']),
(3, 'プログラミング本', 3500.00, 'Books', ['Programming', 'Education', 'Go']);


Golangからアクセスしてみる

Go用のDuckDBドライバーを使ってアクセスしてみる。

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/marcboeker/go-duckdb"
)

type User struct {
	ID   int
	Name string
	Age  int
}

func main() {
	// DuckDBファイルに接続
	db, err := sql.Open("duckdb", "sample.duckdb")
	if err != nil {
		log.Fatal("接続エラー:", err)
	}
	defer db.Close()

	// 接続テスト
	if err := db.Ping(); err != nil {
		log.Fatal("Pingエラー:", err)
	}
	fmt.Println("✓ DuckDBに接続しました")

	// ユーザー一覧取得
	rows, err := db.Query("SELECT id, name, age FROM users")
	if err != nil {
		log.Fatal("クエリエラー:", err)
	}
	defer rows.Close()

	fmt.Println("=== ユーザー一覧 ===")
	for rows.Next() {
		var user User
		err := rows.Scan(&user.ID, &user.Name, &user.Age)
		if err != nil {
			log.Fatal("スキャンエラー:", err)
		}
		fmt.Printf("ID: %d, 名前: %s, 年齢: %d\n", user.ID, user.Name, user.Age)
	}
}

まとめ

DuckDBを触ってみた感想:

良い点

  • セットアップが簡単(単一ファイル)
  • Goとの統合が楽(標準のdatabase/sql)

気になる点

  • 同時書き込み制限
  • 基本的にはRead Heavyな洗い替え用途で個人にキャッシュ撒くとかだろうなあ....

特にサーバーレス環境での分析基盤として面白い選択肢になりそう。

次はLambda + EFSとかで動かしてみよう。
Function Urls経由でAWS QuickSightとかからクエリ打ってみるのもおもしろいかも?


記事

....この記事は手元の感想メモとこれまでのブログ記事MCPから claude 4 sonnetが書きました。

こうしてインターネット汚染が。