0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cloudflareの無料枠を考える前に、公開データをSQLiteと静的配信へ分ける

0
Last updated at Posted at 2026-09-26

公開データの置き場所を見直す

Cloudflareでサービスを増やすと、無料枠はどこで足りなくなるのか。Supabaseの容量まで考えているうちに、公開データの原本をローカルのSQLiteへ置き、静的配信する方針に落ち着きました。

これは移行前の設計記録です。原本は手元で管理し、公開用のHTML・JSONだけを配布する。お気に入りやメモなど、利用者が保存するデータはクラウドDBに残します。移行後の費用削減を実測した記事ではありません。

題材は、自作の学校検索サービス「まなびマップ」です。通える高校を地図で見ながら、親子で決める。

Web版は https://manabi-map.app から開けます。地点を検索し、周辺の高校を地図で探すところから試せます。Starをいただけると励みになります。

以前、サービス名とURLを分けて考えた記事を書きました。今回は、その先で複数のサービスをどう置き、どこに費用がかかるかを考えた続きです。

記事の要約

公開情報は「原本を編集する場所」と「みんなが読む場所」に分けます。個人のメモは別の経路で保存し、公開ファイルへ混ぜません。

月5ドルと言われても、まだ判断できなかった

学校の種類を増やし、漢字やかるた、土地の情報も扱いたい。そうすると、いまの配信先でどこまで持つのかが気になります。

最初は料金と上限を表にしました。でも、これだけでは決められませんでした。

知りたいのは「月額はいくらです」よりも、「予定している量を置いたら、上限の何割になるのか」です。ファイル数なのか、巨大なJSONなのか、利用者の保存データなのか。引っかかる場所で対処が変わります。

たとえば、Cloudflare PagesのFreeは1サイトあたり20,000ファイル、1ファイル25MiBまでです。一方、Workers Paidの月額最低5米ドルは動的処理側の料金です。この5ドルでPagesのファイル数制限まで解決するとは扱えません。Pagesの制限、Workersの料金で別々に確認します。

以下の外部サービスの条件は2026年9月27日に確認したものです。実際に構成を変えるときは、契約プランと公式ページを再確認します。

棒グラフにして、ようやく話が進んだ

検討用HTMLには、予定件数を入れると使用率が変わるバーを付けました。80%までは緑、80%超は黄、100%超は赤。80%は運用上の目安として置いた線で、サービス提供元の制限ではありません。

説明用の仮定で、1件につきHTMLとJSONを1つずつ出し、共通ファイルが1,000個あるとします。

1サイトの予測ファイル数 = 件数 × 2 + 1,000

 6,000件 → 13,000ファイル → 20,000の65%
10,000件 → 21,000ファイル → 20,000の105%

これは本番の件数ではありません。何を数えるかを揃えるための例です。一覧、画像、検索索引、言語別ページが増えれば式も変えます。最後は生成物の実数を数えます。

容量を別々の物差しで確認する

ファイル数が65%でも、最大JSONが制限を超えていれば配布できません。全体の平均ではなく、最も余裕のない項目を見ます。

計画を見直す途中でも、新しい分割JSONだけを見て、互換性のために残す既存の大きなAPIファイルを見落としかけました。新構成で残るものまで含めないと、バーは簡単に楽観的になります。

東西に分ける案は、配信単位の話だった

学校を全国横断で探す人ばかりではありません。学校種別や地域ごとに配信先を分け、総合入口から案内する構成は候補になります。

ただし、east.example.comとwest.example.comという名前を付けるだけでは、保存枠は増えません。同じPagesプロジェクトを参照しているなら、ファイルは同じ場所にあります。分ける対象はURLの見た目だけでなく、生成物とデプロイ先です。

別プロジェクトへ分けても、各地域の共通ファイルは重複します。県境をまたぐ検索や、全国一覧への入口も必要です。分割数が増えるほど更新の確認先も増えます。

Pagesにはアカウントのプロジェクト数など別の上限もあります。細分化すれば無制限に無料、とは考えません。公式の制限一覧を見ながら、まず利用者に自然な単位を選びます。具体的な地域割りはまだ決めていません。

そもそも、全部をクラウドDBに置く必要があるのか

ここで前提を変えました。

学校や教材の公開情報は、運営側が整備して公開するときに変わります。利用者のメモは、その人が保存するたびに変わります。同じDBに置けるからといって、同じ更新経路にする必要はありません。

データ 採用した置き場所 反映するタイミング
学校・教材などの公開情報の原本 ローカルSQLite 運営が編集・確認するとき
閲覧用のHTML・JSON 静的ファイルの配信先 公開処理を終えたとき
個人のお気に入り・メモ クラウドDB 利用者が保存するとき

原本から公開する列だけを取り出し、HTMLやJSONへ変換します。SQLiteファイルをそのまま公開する構成にはしません。非公開の管理項目や、利用者データが紛れ込まない検査も生成処理に入れます。

概念としては、編集用の台帳と配布用の冊子を分ける形です。台帳を置いた机に、読者全員が来る必要はありません。

原本のPCを閉じても公開済みの情報は読める

ローカルPCは公開情報を作るために使います。公開後の閲覧は配布済みのファイルを読むので、PCを常時起動しておく必要はありません。

代わりに、原本を編集しただけではWebへ反映されなくなります。「更新を受け付けた」「原本へ取り込んだ」「公開できた」は分けて扱う必要があります。即時公開が必要なデータには、この方式が合わないこともあります。

ローカルの原本なら、SQLiteから始められそうだった

原本を整備する人数と、サイトを読む人数は別です。閲覧が増えても、閲覧リクエストがローカルSQLiteに届くわけではありません。

今回ほしいのは、サービスごとの原本を管理し、公開用の読み取り結果を取り出すことです。初期段階ではMariaDBやMySQLのサーバーを常駐させるより、SQLiteで始める方針にしました。

SQLiteも同時書込みには制約があります。複数人が継続的に編集する運用へ変わったら、編集の待ち時間や衝突を測り直します。「小さいDBだから」より、「この原本の使い方に合うか」で選びます。SQLiteの適した用途

原本はサービスごとに1つ。配信先を東西に分けても、東西それぞれに書込み用DBを作る予定はありません。地域分割は原本から取り出す段階で行います。

公開処理の候補は、ローカルで生成・検査した成果物をCloudflare PagesのDirect Uploadへ渡す方法です。既存のGit連携とは更新の入口が変わるので、自動デプロイとの競合まで整理します。Direct Uploadの公式手順

コピーを増やす前に、正本を1つにする

SQLiteならファイルとして保存できるので、別ディスクやGoogle Driveへ控えを置けます。ただ、稼働中のDBファイルをそのまま同期フォルダへ置く方針にはしません。

編集する原本は1つに固定し、整合したスナップショットを作ってから世代保存します。SQLiteにはOnline Backup APIなど、そのための仕組みがあります。SQLiteのバックアップ方法

別ドライブへ置いても、同じ物理ディスクなら故障への備えは限られます。同期先で削除が伝わることもあるので、「同じファイルが2つ見える」と「前の状態へ戻せる」も別です。

確認したいのは、取り出したバックアップから原本を開き、公開用データを再生成できるところまで。保存先や保持世代は、これから具体化します。

クラウドの元データは、最後に小さくする

移行計画で気になったのは、利用者の保存情報とのつながりでした。

学校IDを参照するお気に入りやメモがあり、削除連鎖のある外部キーを残したまま参照先を消すと、利用者データまで消えるおそれがあります。SQLiteへコピーできたから旧データを削除、とは進められません。

移行は次の順で考えています。

  1. 合成データでSQLiteへの取込みと公開用出力を作る。
  2. バックアップと復元を確認する。
  3. 学校IDの参照、管理画面の修正受付、認証・権限、配布処理をつなぎ直す。
  4. 実データで切替と復元を検証してから、不要になった旧原本を縮小する。

利用者の保存を守りながら4段階で移行する

原本の取込み、復元、参照と権限の準備を先に済ませます。旧データの縮小は、実際の切替を検証した後です。

参照用の最小限のID台帳をクラウドに残す案などを比較します。クラウドDBから公開情報を一切なくすことより、利用者の保存内容と権限を保つことを優先します。

これなら無料か、は項目ごとに答える

静的化で、公開マスターをクラウドDBへ置く容量と、その読取りを減らせる見込みはあります。それでも個人メモ、認証、動的な処理、通信量は残ります。

Supabaseでは、データだけでなく索引もDB容量に含まれます。公開JSONが何MBかだけでDB使用量は計算できません。FreeのDB容量上限は500MBなので、固定部分と利用者ごとの増加分を分け、実際のDB指標と照合していきます。DBとディスク容量の説明

運営側の生成時間や復元の手間も費用です。複雑な分割を増やすより、必要な箇所へ課金する方が楽になる場面もあると思います。

今回決められたのは、公開情報が増える量と、利用者が増える量を別々に見積もる構成です。無料で続けられる範囲を確かめやすくし、足りなくなった項目を見て次を選びます。

学校を地図とメモで比較したい方へ

  • 通える範囲の高校を地図で見たい方。
  • 説明会や文化祭で見聞きしたことを、学校ごとに残したい方。
  • 掲載された数字の根拠を確かめながら、家族で検討したい方。

現在のWeb版はまなびマップで試せます。今回のSQLite移行は計画段階で、現行版の新機能としてはまだ提供していません。

Starをいただけると開発の励みになります。

あわせて読みたい

まずは原本を作るところから

料金表を何度も見ていたのに、話が進んだのは「このデータは誰が、いつ変えるのか」を考え直してからでした。

次は合成データで原本と生成処理を作ります。公開用データを同じ条件で取り出せることと、バックアップから戻せることを、順に確かめていく予定です。


📎 図解版・関連リンクをまとめたページがあります:
https://ishizakahiroshi.com/articles/2026/2026-09-27_sqlite-static-source-design/

※ ヘッダー画像とインフォグラフィックの絵は AI(画像生成)で作成しています。

※ 本文の挿絵も AI(画像生成)で作成しています。

書いた人: ishizakahiroshi
群馬の北部で、保護猫2匹と暮らす、在宅エンジニア(何でも屋)
https://ishizakahiroshi.com/
https://github.com/ishizakahiroshi
X(業務委託・各種相談はこちら):
https://x.com/ishizakahiroshi

バックエンド・インフラ・AI連携まわりで、業務委託のご相談を受け付けています。フルリモートです。スポットや週2〜3時間からでも歓迎で、いろんな案件に携われたらうれしいです。こんな相談、歓迎です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?