DB設計書
最終更新: 2026/07/21
9
テーブル数
111
総カラム数
5
ドメイン数
ER図
ユーザー・認証
1 tablesusers
ユーザー · 9 columns
Clerk認証と連携するユーザーテーブル。Webhookで自動同期。
IDXIDX(clerk_id)
IDXIDX(email)
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
| id | UUID | PK | 主キー |
| clerk_id | VARCHAR(255) | NOT NULLUNIQUE | Clerk側のユーザーID |
| VARCHAR(255) | NOT NULL | メールアドレス | |
| display_name | VARCHAR(255) | 表示名 | |
| avatar_url | TEXT | アバター画像URL | |
| preferences | JSONB | DEFAULT {} | ユーザー設定 |
| is_active | BOOLEAN | NOT NULLDEFAULT true | アカウント有効フラグ |
| created_at | TIMESTAMPTZ | NOT NULL | 作成日時 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新日時 |
コンテンツ・ブックマーク
3 tablescontents
コンテンツ · 18 columns
URLごとのコンテンツ情報。全ユーザー共有。同じURLは1レコード。
IDXUNIQUE(canonical_url)
IDXIDX(platform)
IDXIDX(scrape_status)
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
| id | UUID | PK | 主キー |
| url | TEXT | NOT NULL | オリジナルURL |
| canonical_url | TEXT | NOT NULL | 正規化URL |
| platform | ENUM | NOT NULLDEFAULT other | youtube/tiktok/instagram/twitter/web_article/blog/news/other |
| title | VARCHAR(500) | タイトル | |
| description | TEXT | 概要・説明文 | |
| text_content | TEXT | 抽出された本文テキスト | |
| language | VARCHAR(10) | 言語コード | |
| author_name | VARCHAR(255) | 投稿者名 | |
| author_url | TEXT | 投稿者URL | |
| published_at | TIMESTAMPTZ | 公開日時 | |
| thumbnail_url | TEXT | サムネイル | |
| og_data | JSONB | OGメタデータ | |
| structured_data | JSONB | JSON-LD構造化データ | |
| scrape_status | VARCHAR(20) | NOT NULLDEFAULT pending | 処理状況 |
| word_count | INTEGER | 文字数 | |
| created_at | TIMESTAMPTZ | NOT NULL | 作成日時 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新日時 |
bookmarks
ブックマーク · 8 columns
ユーザーの保存行動。「誰が・いつ・どのコンテンツを保存したか」。
IDXIDX(user_id)
IDXIDX(content_id)
IDXUNIQUE(user_id, content_id)
IDXIDX(processing_status)
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
| id | UUID | PK | 主キー |
| user_id | UUID | NOT NULLFK → users | 保存ユーザー |
| content_id | UUID | NOT NULLFK → contents | 対象コンテンツ |
| note | TEXT | 個人メモ | |
| is_favorite | BOOLEAN | NOT NULLDEFAULT false | お気に入り |
| processing_status | VARCHAR(20) | NOT NULLDEFAULT pending | 処理状況 |
| created_at | TIMESTAMPTZ | NOT NULL | 作成日時 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新日時 |
medias
メディア · 12 columns
汎用メディアテーブル。エンティティ/コンテンツ/リストにポリモーフィックに紐づけ。
IDXIDX(target_type, target_id)
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
| id | UUID | PK | 主キー |
| url | TEXT | NOT NULL | Vercel Blob URL |
| source_url | TEXT | 元URL | |
| mime_type | VARCHAR(100) | MIMEタイプ | |
| width | INTEGER | 幅(px) | |
| height | INTEGER | 高さ(px) | |
| is_primary | BOOLEAN | NOT NULLDEFAULT false | メイン画像 |
| position | INTEGER | NOT NULLDEFAULT 0 | 表示順 |
| target_type | ENUM | NOT NULL | entity/content/list |
| target_id | UUID | NOT NULL | 紐づけ先ID |
| created_at | TIMESTAMPTZ | NOT NULL | 作成日時 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新日時 |
エンティティ
2 tablesentities
エンティティ · 21 columns
店舗・商品・場所・作品等。全ユーザー共有の公開データ。カテゴリ別メタデータはJSONB。
IDXIDX(category)
IDXIDX(city)
IDXIDX(latitude, longitude)
IDXIDX(mention_count)
IDXGIN(name gin_trgm_ops)
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
| id | UUID | PK | 主キー |
| name | VARCHAR(500) | NOT NULL | エンティティ名 |
| slug | VARCHAR(600) | NOT NULLUNIQUE | URLスラッグ |
| category | ENUM | NOT NULL | restaurant/cafe/book/product等(20種) |
| description | TEXT | AI生成の説明文 | |
| aliases | JSONB | DEFAULT [] | 別名リスト (Entity Resolution用) |
| latitude | REAL | 緯度 | |
| longitude | REAL | 経度 | |
| address | TEXT | 住所 | |
| city | VARCHAR(255) | 都市名 | |
| country | VARCHAR(100) | 国名 | |
| postal_code | VARCHAR(20) | 郵便番号 | |
| metadata | JSONB | DEFAULT {} | カテゴリ別メタデータ |
| google_place_id | VARCHAR(255) | Google Place ID | |
| website_url | TEXT | 公式サイト | |
| phone_number | VARCHAR(50) | 電話番号 | |
| mention_count | INTEGER | NOT NULLDEFAULT 0 | 言及数 |
| thumbnail_url | TEXT | サムネイル | |
| created_at | TIMESTAMPTZ | NOT NULL | 作成日時 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新日時 |
| deleted_at | TIMESTAMPTZ | 論理削除 |
content_entities
コンテンツ-エンティティ関連 · 9 columns
多対多リレーション。AI抽出結果の確信度・感情分析を保持。
IDXUNIQUE(content_id, entity_id)
IDXIDX(entity_id)
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
| id | UUID | PK | 主キー |
| content_id | UUID | NOT NULLFK → contents | 対象コンテンツ |
| entity_id | UUID | NOT NULLFK → entities | 対象エンティティ |
| context | TEXT | 文脈テキスト | |
| sentiment | VARCHAR(20) | positive/neutral/negative | |
| confidence | REAL | AI確信度(0.0〜1.0) | |
| order_in_content | INTEGER | 出現順序 | |
| created_at | TIMESTAMPTZ | NOT NULL | 作成日時 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新日時 |
リスト
2 tableslists
リスト · 13 columns
表示形式(list/map/gallery等)と公開設定(private/shared/public)を持つ。
IDXIDX(user_id)
IDXIDX(share_token)
IDXIDX(visibility)
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
| id | UUID | PK | 主キー |
| user_id | UUID | NOT NULLFK → users | オーナー |
| name | VARCHAR(255) | NOT NULL | リスト名 |
| description | TEXT | 説明 | |
| emoji | VARCHAR(10) | アイコン | |
| cover_image_url | TEXT | カバー画像 | |
| view_type | ENUM | NOT NULLDEFAULT list | list/grid/map/gallery/bookshelf |
| visibility | ENUM | NOT NULLDEFAULT private | private/shared/public |
| share_token | VARCHAR(64) | UNIQUE | 共有トークン |
| item_count | INTEGER | NOT NULLDEFAULT 0 | アイテム数 |
| created_at | TIMESTAMPTZ | NOT NULL | 作成日時 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新日時 |
| deleted_at | TIMESTAMPTZ | 論理削除 |
list_items
リストアイテム · 9 columns
エンティティ単位またはコンテンツ単位で保存可能。手動並べ替え対応。
IDXIDX(list_id)
IDXIDX(entity_id)
IDXIDX(list_id, position)
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
| id | UUID | PK | 主キー |
| list_id | UUID | NOT NULLFK → lists | 所属リスト |
| item_type | ENUM | NOT NULL | entity/content |
| entity_id | UUID | FK → entities | エンティティ |
| content_id | UUID | FK → contents | コンテンツ |
| note | TEXT | メモ | |
| position | INTEGER | NOT NULLDEFAULT 0 | 並び順 |
| created_at | TIMESTAMPTZ | NOT NULL | 作成日時 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新日時 |
AI処理
1 tablesprocessing_jobs
処理ジョブ · 12 columns
AI処理パイプラインの各ステップ進捗とエラーを追跡。
IDXIDX(bookmark_id)
IDXIDX(status)
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
| id | UUID | PK | 主キー |
| bookmark_id | UUID | NOT NULLFK → bookmarks | 対象ブックマーク |
| content_id | UUID | NOT NULLFK → contents | 対象コンテンツ |
| retry_count | INTEGER | NOT NULLDEFAULT 0 | リトライ回数 |
| status | VARCHAR(20) | NOT NULLDEFAULT pending | pending/scraping/extracting/resolving/enriching/suggesting/complete/failed |
| current_step | VARCHAR(50) | 現在ステップ | |
| error | TEXT | エラーメッセージ | |
| metadata | JSONB | トークン消費量等 | |
| started_at | TIMESTAMPTZ | 開始時刻 | |
| completed_at | TIMESTAMPTZ | 完了時刻 | |
| created_at | TIMESTAMPTZ | NOT NULL | 作成日時 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新日時 |
設計方針メモ
DBNeon PostgreSQL(サーバーレス)+ Drizzle ORM。型安全なクエリ
UUID全テーブルのPKはUUID v4。分散生成可能
コンテンツ共有同じURLは1つのcontentsレコード。bookmarksがユーザーごとの保存行動
エンティティ全ユーザー共有の公開データ。カテゴリ別メタデータはJSONB(discriminated union)
重複検出entities.aliases JSONB + pg_trgm GINインデックス + 多重シグナルスコアリング + LLM確認
リストアイテムentity単位またはcontent単位で保存可能(ポリモーフィック)
ソフトデリートentities/listsのみ deleted_at による論理削除。他は物理削除
認証Clerk(ヘッドレス)。Webhookでusersテーブルに自動同期
AI処理waitUntil + 自前async関数。Vercel Pro最大300秒。スケール後はジョブキューに移行可
メディアsharp→WebP変換→Vercel Blob + CDN。汎用mediasテーブルでポリモーフィック管理