データストアの使い分け
プロダクトごとにデータの置き場所が違う。同じものを使い回していない。
| プロダクト | 置き場所 | 中身 |
|---|---|---|
| ちょうぼっち | Supabase (PostgreSQL) | 利用者ごとの帳簿。書き込みが多い |
| Valscope | Turso (libSQL) | 開示データ。ほぼ読むだけ |
| サムネジェネレーター | IndexedDB(端末内) | モデルのキャッシュ。サーバに持たない |
分ける基準
利用者ごとにデータを分ける必要があるなら 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 のままという前提を崩していない。
暫定の構成を入れるときは、戻す条件を書き残しておく。 書かないと、暫定がそのまま本番になる。