データストアの使い分け

更新: 2026-09-09
SupabaseTursolibSQLVercel

プロダクトごとにデータの置き場所が違う。同じものを使い回していない。

プロダクト置き場所中身
ちょうぼっちSupabase (PostgreSQL)利用者ごとの帳簿。書き込みが多い
ValscopeSQLite ファイル(Blob配信)開示データ。ほぼ読むだけ。旧構成は Turso (libSQL)
サムネジェネレーターIndexedDB(端末内)モデルのキャッシュ。サーバに持たない

分ける基準

書き込み多い少ない利用者ごとに分ける必要 なしありSupabaseTurso (libSQL)認証と行レベルの制御が要る読み取りが主。配信が速いちょうぼっちValscope
「利用者ごとにデータを分ける必要があるか」で最初に分かれる。

利用者ごとにデータを分ける必要があるなら Supabase。 認証と、行レベルでアクセスを制御する仕組みが最初から付いてくる。 これを自前で作るのは割に合わない。

全員が同じデータを読むだけなら Turso。 Valscope の開示データは誰が見ても同じで、更新は取り込み処理のときだけ。 書き込みの同時実行を考えなくていいぶん、構成が単純になる。

Turso を選んだ理由

Valscope は2万社を超える企業データを持つ。素朴に1つのSQLiteファイルを 配信する作りにすると、ファイルが大きくなって配信が持たなくなる。

Turso は libSQL のクライアント(@libsql/client)からHTTPで引ける。 アプリ側はファイルを持たず、必要な行だけ取りにいく。

import { createClient } from "@libsql/client";

const client = createClient({
  url: process.env.TURSO_DATABASE_URL!,
  authToken: process.env.TURSO_AUTH_TOKEN,
});

無料枠で運用するための制約

読み取り行数に上限がある。 SELECT * を軽い気持ちで書くと枠を食う。 一覧に出す列だけを指定する。

キャッシュを挟む。 同じ企業のページを何度も引かない。 Next.js の unstable_cache で秒数を決めて包み、TTLは1か所に定数として置いている。 散らばると、どこを直せば効くのか分からなくなる。

書き込みが要らないものはビルド時に固める。 静的書き出しできるページは リクエストのたびにDBを引かない。

Vercel Blob の位置づけ

Valscope では一時的に Blob 経由でデータベースファイルを配ったことがある。 当初は「暫定処置で、正本は Turso のまま」と書いていた。

2026-09-09、その暫定が本番になった。 Turso をデータ経路から完全に外し、 データレイクから SQLite ファイルを直接作って Blob で配る形へ寄せている。 Turso が担っていたのは中継だけで、読み出しは既に Blob 経由になっていたため、 中継を残す理由が無くなった。手順はSQLiteを1経路で作る

暫定の構成を入れるときは、戻す条件を書き残しておく。 書かないと、暫定がそのまま本番になる。ここではまさにそうなった。 恒久化するなら、恒久化したと書き直すところまでやる。

関連

WIKI一覧へ