はじめに
期限付きコンテンツを作るとき、多くの人がまず悩むのが「データをどこに保存するか」ではないでしょうか。
リレーショナルデータベースを立てるのが王道ですが、一時ページやイベントギャラリーのような補助的な機能に、そこまでの重装備は必要ありません。
この記事では、私がVercel KV(キーバリューストア)だけで一時コンテンツを管理した理由と、その具体的なデータ設計を解説します。
「DBを立てずに済ませる」という選択が、なぜこのケースで正解になるのか。ストレージの選び方から、キー設計、TTLの使いどころまで、実際に手を動かした知見を共有します。
なぜKVを選んだのか
DBを立てるコストを避ける
リレーショナルデータベースは強力ですが、それなりの初期コストと運用コストがかかります。
スキーマを設計し、マイグレーションを管理し、接続プールやバックアップに気を配る。本格的なデータを扱うならこの手間に見合いますが、一時ページのように「一定期間だけ存在して消える」データには、正直オーバースペックなんです。
KVなら、キーと値を put / get するだけ。テーブル設計もSQLも要りません。立ち上げの速さと運用の軽さは、こうした小回りの利く機能でこそ効いてきます。
キーバリューが向いているデータ
一時ページのデータは、構造としてとてもシンプルです。
「slug(URLの一部)を指定したら、そのページの本文・画像・有効期限が返ってくる」——これはまさにキーバリューが得意とするアクセスパターンです。複雑な結合や横断検索はほとんど発生しません。
一覧表示が必要な管理画面用には、slugのインデックスを別のキーに持たせておけば十分対応できます。データの形が素直だからこそ、KVというシンプルな道具がぴたりとハマるわけです。
Vercelとの相性
このシステムはVercel上で動かしているので、Vercel KVを使うと統合が非常にスムーズでした。
環境変数を設定するだけで接続でき、サーバーレス関数からそのまま読み書きできます。別途インフラを立てたり、接続情報を厳重に管理したりする必要がありません。
プラットフォームが提供する道具を素直に使うと、構成がシンプルに保たれ、トラブルの種も減ります。「使えるものは使う」——このあたりの割り切りも設計判断のうちですよね。
データ設計の要点
キー設計とデータ構造
KVでは、キーの付け方がそのまま設計の良し悪しを決めます。
私は page:{slug} のような接頭辞付きのキーで、各一時ページのデータをまとめて保存しています。値には本文、画像のURL、有効期限、公開状態などをJSONでひとまとめにしておきます。
接頭辞(プレフィックス)を付けておくと、種類ごとにデータを整理でき、後から別のコンテンツ種別を足すときも名前が衝突しません。地味ですが、最初にルールを決めておくと運用がぐっと楽になります。
有効期限の持ち方
有効期限は、データの中に明示的なフィールドとして持たせています。
たとえば expiresAt に「2026-03-31T23:59:59」のようなISO形式の日時を入れておく。これにより、Cronが期限を判定するときも、公開ページがアクセス可否を確かめるときも、同じ値を見るだけで済みます。
「いつ消えるか」をデータ自身が知っている状態にしておくのがポイントです。期限の判断ロジックがあちこちに散らばらず、一箇所に集約できるので、後から仕様を変えるときも安心です。
画像はどこに置くか
本文はKVに入れても軽いのですが、画像を直接KVに詰め込むのは避けています。
イベントギャラリーの写真などは、画像配信に強いCloudinaryに置き、KVにはそのURLだけを保存する構成です。KVはあくまでメタデータと本文を扱い、重いバイナリは専用のストレージに任せる。役割分担ですね。
こうしておくと、KVのデータは軽量に保たれ、画像の変換やリサイズもCloudinary側に任せられます。それぞれの道具を得意分野で使う、という素直な設計です。
本文・有効期限・公開状態 画像URL(参照だけ)
ギャラリー画像の実体 変換・リサイズも担当
KVからメタデータを、Cloudinaryから画像を組み立てて表示
TTLと明示フラグの使い分け
KVのTTLで自動削除する
KVには**TTL(Time To Live)**という便利な機能があります。データを保存するときに寿命を秒数で指定しておくと、その時間が過ぎたら自動的にデータが消えてくれる仕組みです。
「期限が来たら跡形もなく消えてよい」データなら、これがいちばん手軽です。Cronすら待たずに、KV自身が掃除をしてくれます。有効期限までの秒数を計算してTTLに渡すだけ、と実装もシンプルです。
消し忘れが物理的に起こり得なくなる、というのがTTLの強みですね。
履歴を残したいときは明示管理
一方で、「失効したけれどデータは残しておきたい」ケースもあります。
たとえば、失効後に「このページは公開を終了しました」と案内を出したいとき。TTLで消してしまうと、この案内すら出せなくなります。そういう場合は、TTLに頼らず expiresAt フィールドと公開フラグで明示的に管理します。
期限が来たかどうかはCronや表示時に日時を比較して判断し、データ自体は残す。失効=削除ではなく、失効=非公開として扱えるようにしておくと、運用の選択肢が広がります。
完全に消してよいデータ向け。実装が最もシンプルで、消し忘れが物理的に起きない
案内表示や履歴を残したいデータ向け。データは保持し、公開状態だけを切り替える
使い分けの目安
「消えても困らない使い捨てデータ」ならTTL、「後から参照・案内したいデータ」なら明示フラグ。この線引きを最初に決めておくと、実装がぶれません。
まとめ
一時コンテンツの管理に、必ずしも重量級のデータベースは要りません。データの形がシンプルで、寿命が限られているなら、KVという軽い道具のほうが立ち上げも運用も楽なんです。
ポイントは3つ。接頭辞付きのキーでデータを整理すること、有効期限をデータ自身に持たせること、そしてTTLと明示フラグを要件で使い分けること。この設計が、後片付けの自動化を支える土台になります。
保存したデータを実際に「期限が来たら失効させる」処理は、Cronが担います。その仕組みは「Cronによる自動失効とアクセス制御」で詳しく解説しています。全体像を振り返りたい方は、ハブ記事「期限付きコンテンツの自動失効」もあわせてどうぞ。