DB設計書

最終更新: 2026/07/21

9

テーブル数

111

総カラム数

5

ドメイン数

ER図

1:N1:N1:N1:N1:N1:N1:N1:N1:N1:Nusersユーザーlistsリストbookmarksブックマークlist_itemsリストアイテムcontentsコンテンツentitiesエンティティprocessing_jobs処理ジョブcontent_entitiesコンテンツ-エンティティ関連mediasメディア

ユーザー・認証

1 tables

users

ユーザー · 9 columns

Clerk認証と連携するユーザーテーブル。Webhookで自動同期。

IDXIDX(clerk_id)
IDXIDX(email)
カラム制約説明
idUUID
PK
主キー
clerk_idVARCHAR(255)
NOT NULLUNIQUE
Clerk側のユーザーID
emailVARCHAR(255)
NOT NULL
メールアドレス
display_nameVARCHAR(255)
表示名
avatar_urlTEXT
アバター画像URL
preferencesJSONB
DEFAULT {}
ユーザー設定
is_activeBOOLEAN
NOT NULLDEFAULT true
アカウント有効フラグ
created_atTIMESTAMPTZ
NOT NULL
作成日時
updated_atTIMESTAMPTZ
NOT NULL
更新日時

コンテンツ・ブックマーク

3 tables

contents

コンテンツ · 18 columns

URLごとのコンテンツ情報。全ユーザー共有。同じURLは1レコード。

IDXUNIQUE(canonical_url)
IDXIDX(platform)
IDXIDX(scrape_status)
カラム制約説明
idUUID
PK
主キー
urlTEXT
NOT NULL
オリジナルURL
canonical_urlTEXT
NOT NULL
正規化URL
platformENUM
NOT NULLDEFAULT other
youtube/tiktok/instagram/twitter/web_article/blog/news/other
titleVARCHAR(500)
タイトル
descriptionTEXT
概要・説明文
text_contentTEXT
抽出された本文テキスト
languageVARCHAR(10)
言語コード
author_nameVARCHAR(255)
投稿者名
author_urlTEXT
投稿者URL
published_atTIMESTAMPTZ
公開日時
thumbnail_urlTEXT
サムネイル
og_dataJSONB
OGメタデータ
structured_dataJSONB
JSON-LD構造化データ
scrape_statusVARCHAR(20)
NOT NULLDEFAULT pending
処理状況
word_countINTEGER
文字数
created_atTIMESTAMPTZ
NOT NULL
作成日時
updated_atTIMESTAMPTZ
NOT NULL
更新日時

bookmarks

ブックマーク · 8 columns

ユーザーの保存行動。「誰が・いつ・どのコンテンツを保存したか」。

IDXIDX(user_id)
IDXIDX(content_id)
IDXUNIQUE(user_id, content_id)
IDXIDX(processing_status)
カラム制約説明
idUUID
PK
主キー
user_idUUID
NOT NULLFK → users
保存ユーザー
content_idUUID
NOT NULLFK → contents
対象コンテンツ
noteTEXT
個人メモ
is_favoriteBOOLEAN
NOT NULLDEFAULT false
お気に入り
processing_statusVARCHAR(20)
NOT NULLDEFAULT pending
処理状況
created_atTIMESTAMPTZ
NOT NULL
作成日時
updated_atTIMESTAMPTZ
NOT NULL
更新日時

medias

メディア · 12 columns

汎用メディアテーブル。エンティティ/コンテンツ/リストにポリモーフィックに紐づけ。

IDXIDX(target_type, target_id)
カラム制約説明
idUUID
PK
主キー
urlTEXT
NOT NULL
Vercel Blob URL
source_urlTEXT
元URL
mime_typeVARCHAR(100)
MIMEタイプ
widthINTEGER
幅(px)
heightINTEGER
高さ(px)
is_primaryBOOLEAN
NOT NULLDEFAULT false
メイン画像
positionINTEGER
NOT NULLDEFAULT 0
表示順
target_typeENUM
NOT NULL
entity/content/list
target_idUUID
NOT NULL
紐づけ先ID
created_atTIMESTAMPTZ
NOT NULL
作成日時
updated_atTIMESTAMPTZ
NOT NULL
更新日時

エンティティ

2 tables

entities

エンティティ · 21 columns

店舗・商品・場所・作品等。全ユーザー共有の公開データ。カテゴリ別メタデータはJSONB。

IDXIDX(category)
IDXIDX(city)
IDXIDX(latitude, longitude)
IDXIDX(mention_count)
IDXGIN(name gin_trgm_ops)
カラム制約説明
idUUID
PK
主キー
nameVARCHAR(500)
NOT NULL
エンティティ名
slugVARCHAR(600)
NOT NULLUNIQUE
URLスラッグ
categoryENUM
NOT NULL
restaurant/cafe/book/product等(20種)
descriptionTEXT
AI生成の説明文
aliasesJSONB
DEFAULT []
別名リスト (Entity Resolution用)
latitudeREAL
緯度
longitudeREAL
経度
addressTEXT
住所
cityVARCHAR(255)
都市名
countryVARCHAR(100)
国名
postal_codeVARCHAR(20)
郵便番号
metadataJSONB
DEFAULT {}
カテゴリ別メタデータ
google_place_idVARCHAR(255)
Google Place ID
website_urlTEXT
公式サイト
phone_numberVARCHAR(50)
電話番号
mention_countINTEGER
NOT NULLDEFAULT 0
言及数
thumbnail_urlTEXT
サムネイル
created_atTIMESTAMPTZ
NOT NULL
作成日時
updated_atTIMESTAMPTZ
NOT NULL
更新日時
deleted_atTIMESTAMPTZ
論理削除

content_entities

コンテンツ-エンティティ関連 · 9 columns

多対多リレーション。AI抽出結果の確信度・感情分析を保持。

IDXUNIQUE(content_id, entity_id)
IDXIDX(entity_id)
カラム制約説明
idUUID
PK
主キー
content_idUUID
NOT NULLFK → contents
対象コンテンツ
entity_idUUID
NOT NULLFK → entities
対象エンティティ
contextTEXT
文脈テキスト
sentimentVARCHAR(20)
positive/neutral/negative
confidenceREAL
AI確信度(0.0〜1.0)
order_in_contentINTEGER
出現順序
created_atTIMESTAMPTZ
NOT NULL
作成日時
updated_atTIMESTAMPTZ
NOT NULL
更新日時

リスト

2 tables

lists

リスト · 13 columns

表示形式(list/map/gallery等)と公開設定(private/shared/public)を持つ。

IDXIDX(user_id)
IDXIDX(share_token)
IDXIDX(visibility)
カラム制約説明
idUUID
PK
主キー
user_idUUID
NOT NULLFK → users
オーナー
nameVARCHAR(255)
NOT NULL
リスト名
descriptionTEXT
説明
emojiVARCHAR(10)
アイコン
cover_image_urlTEXT
カバー画像
view_typeENUM
NOT NULLDEFAULT list
list/grid/map/gallery/bookshelf
visibilityENUM
NOT NULLDEFAULT private
private/shared/public
share_tokenVARCHAR(64)
UNIQUE
共有トークン
item_countINTEGER
NOT NULLDEFAULT 0
アイテム数
created_atTIMESTAMPTZ
NOT NULL
作成日時
updated_atTIMESTAMPTZ
NOT NULL
更新日時
deleted_atTIMESTAMPTZ
論理削除

list_items

リストアイテム · 9 columns

エンティティ単位またはコンテンツ単位で保存可能。手動並べ替え対応。

IDXIDX(list_id)
IDXIDX(entity_id)
IDXIDX(list_id, position)
カラム制約説明
idUUID
PK
主キー
list_idUUID
NOT NULLFK → lists
所属リスト
item_typeENUM
NOT NULL
entity/content
entity_idUUID
FK → entities
エンティティ
content_idUUID
FK → contents
コンテンツ
noteTEXT
メモ
positionINTEGER
NOT NULLDEFAULT 0
並び順
created_atTIMESTAMPTZ
NOT NULL
作成日時
updated_atTIMESTAMPTZ
NOT NULL
更新日時

AI処理

1 tables

processing_jobs

処理ジョブ · 12 columns

AI処理パイプラインの各ステップ進捗とエラーを追跡。

IDXIDX(bookmark_id)
IDXIDX(status)
カラム制約説明
idUUID
PK
主キー
bookmark_idUUID
NOT NULLFK → bookmarks
対象ブックマーク
content_idUUID
NOT NULLFK → contents
対象コンテンツ
retry_countINTEGER
NOT NULLDEFAULT 0
リトライ回数
statusVARCHAR(20)
NOT NULLDEFAULT pending
pending/scraping/extracting/resolving/enriching/suggesting/complete/failed
current_stepVARCHAR(50)
現在ステップ
errorTEXT
エラーメッセージ
metadataJSONB
トークン消費量等
started_atTIMESTAMPTZ
開始時刻
completed_atTIMESTAMPTZ
完了時刻
created_atTIMESTAMPTZ
NOT NULL
作成日時
updated_atTIMESTAMPTZ
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テーブルでポリモーフィック管理