ライブ・フェス機能 テーブル設計書
最終更新: 2026-05-08 関連 Issue: #528, #776
1. 概要
Vercel Postgres(Neon)上に構築するライブ機能のテーブル設計書。 #527 の結論(Neon 採用・react-leaflet・JIS 2桁コード)を前提とする。
対象テーブル
| テーブル | 種別 | 概要 |
|---|---|---|
venues |
新規 | 会場(住所・座標) |
tours |
新規 | ツアー |
lives |
新規 | 公演(日程・会場) |
member_lives |
新規 | メンバーと公演の紐づけ |
prefecture_codes |
新規 | 都道府県コード変換テーブル |
members |
新規 | members.json 連携先(出身地照合用) |
setlists |
新規 | セットリスト(ツアー・フェス別演奏曲目) |
データストア方針
- ライブ関連データ(本設計書の対象): Neon(Vercel Postgres) を正とする
- 現行データ(メンバー・リリース等): Vercel Blob / JSON を継続
- メンテナンス: VSCode で CSV を直接編集し、シードスクリプトで Neon に投入(#609)
2. テーブル定義
2-1. venues(会場)
会場の基本情報と react-leaflet 表示用の座標を管理する。
CREATE TABLE venues (
venue_id VARCHAR(8) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
prefecture CHAR(2) NOT NULL,
latitude DECIMAL(9,6),
longitude DECIMAL(9,6)
);
| カラム名 | 型 | NOT NULL | 説明 |
|---|---|---|---|
venue_id |
VARCHAR(8) | ✅ | PK。都道府県 JIS 2桁 + 連番 3桁(例: 13001) |
name |
VARCHAR(255) | ✅ | 会場名(例: 日本武道館) |
prefecture |
CHAR(2) | ✅ | JIS 2桁コード(例: 13)。先頭ゼロ保持のため文字列型 |
latitude |
DECIMAL(9,6) | — | 緯度(WGS84。例: 35.693200)。未登録時は NULL |
longitude |
DECIMAL(9,6) | — | 経度(WGS84。例: 139.749700)。未登録時は NULL |
備考:
DECIMAL(9,6)は整数部 3桁・小数部 6桁(精度 約 0.1m)- PostGIS 不使用(精細な地図表示は不要という #527 の方針に準拠)
- 座標未登録の会場はマップ上に表示しない
インデックス:
CREATE INDEX idx_venues_prefecture ON venues (prefecture);
2-2. tours(ツアー)
ツアー単位の情報を管理する。
CREATE TABLE tours (
tour_id VARCHAR(20) PRIMARY KEY,
title VARCHAR(255) NOT NULL,
release_id VARCHAR(255)
);
| カラム名 | 型 | NOT NULL | 説明 |
|---|---|---|---|
tour_id |
VARCHAR(20) | ✅ | PK。年 + 識別子(例: 2026B) |
title |
VARCHAR(255) | ✅ | ツアー名称(例: モーニング娘。'26 コンサートツアー春 – Rays Of Light –) |
release_id |
VARCHAR(255) | — | 関連リリース ID(releases.json の id と対応。FK 制約なし) |
備考:
release_idは Blob 管理の releases.json を参照するため、DB レベルの FK 制約は設けない
2-3. lives(公演)
個別公演の日程・会場・所属ツアーを管理する。
CREATE TABLE lives (
live_id VARCHAR(20) PRIMARY KEY,
tour_id VARCHAR(20) REFERENCES tours (tour_id),
venue_id VARCHAR(8) NOT NULL REFERENCES venues (venue_id),
date DATE NOT NULL,
time TIME,
title VARCHAR(255)
);
| カラム名 | 型 | NOT NULL | 説明 |
|---|---|---|---|
live_id |
VARCHAR(20) | ✅ | PK。ツアー ID + 連番 3桁(例: 2026B001) |
tour_id |
VARCHAR(20) | — | FK → tours(tour_id)。単独公演は NULL |
venue_id |
VARCHAR(8) | ✅ | FK → venues(venue_id) |
date |
DATE | ✅ | 公演日(例: 2026-04-11) |
time |
TIME | — | 開演時刻(例: 13:00:00)。00:00 は時刻不明を意味し、画面上は時刻を表示しない |
title |
VARCHAR(255) | — | 公演タイトル。ツアー名と異なる場合のオーバーライド用 |
インデックス:
CREATE INDEX idx_lives_tour_id ON lives (tour_id);
CREATE INDEX idx_lives_venue_id ON lives (venue_id);
CREATE INDEX idx_lives_date ON lives (date);
2-4. member_lives(メンバー × 公演紐づけ)
メンバーと公演の多対多関係を管理する(#517 で使用)。
CREATE TABLE member_lives (
member_id VARCHAR(50) NOT NULL,
live_id VARCHAR(20) NOT NULL REFERENCES lives (live_id),
PRIMARY KEY (member_id, live_id)
);
| カラム名 | 型 | NOT NULL | 説明 |
|---|---|---|---|
member_id |
VARCHAR(50) | ✅ | members.json の id と対応。FK 制約なし |
live_id |
VARCHAR(20) | ✅ | FK → lives(live_id) |
備考:
member_idは Blob 管理の members.json を参照するため、DB レベルの FK 制約は設けない- PK = (member_id, live_id) の複合主キーで重複を防ぐ
インデックス:
CREATE INDEX idx_member_lives_live_id ON member_lives (live_id);
2-5. prefecture_codes(都道府県コード変換)
members.birthplace(自由文字列)を JIS 2桁コードに変換するための参照テーブル(#520 ご当地ライブ検出で使用)。
CREATE TABLE prefecture_codes (
prefecture_code CHAR(2) PRIMARY KEY,
name VARCHAR(20) NOT NULL,
aliases TEXT[]
);
| カラム名 | 型 | NOT NULL | 説明 |
|---|---|---|---|
prefecture_code |
CHAR(2) | ✅ | PK。JIS 2桁コード(例: 13) |
name |
VARCHAR(20) | ✅ | 都道府県名(例: 東京都) |
aliases |
TEXT[] | — | 別表記の配列(例: {"東京", "東京 ", "Tokyo"}) |
備考:
aliasesはbirthplaceの表記ゆれ吸収のために使用(部分一致マッチング)- 初期データ: 47都道府県分を CSV(
prefecture.csv)からシード投入 - 海外拡張コード(#674): 海外公演対応のため以下3コードを追加(
aliasesは空)
prefecture_code |
name |
対象地域 |
|---|---|---|
50 |
アジア | 韓国・台湾・香港・中国など |
60 |
ヨーロッパ | フランスなど |
70 |
北中米 | 米国・メキシコなど |
2-6. members(出身地照合用)
Blob の members.json から出身地情報のみを複製し、会場の都道府県との照合に使用する(#520 専用テーブル)。
CREATE TABLE members (
member_id VARCHAR(50) PRIMARY KEY,
birthplace VARCHAR(255)
);
| カラム名 | 型 | NOT NULL | 説明 |
|---|---|---|---|
member_id |
VARCHAR(50) | ✅ | PK。members.json の id と一致 |
birthplace |
VARCHAR(255) | — | 出身地の自由文字列(例: 東京都港区)。未設定時は NULL |
備考:
- members.json の
profile.birthplaceを定期同期または手動投入 - 都道府県コードへの変換は
prefecture_codesテーブルとのマッチングでアプリ層が担当 - この
membersテーブルは Blob の members.json を置き換えるものではない
2-7. festivals(フェス)
参加フェスの開催情報を管理する。複数日開催フェスのうち参加する1日を1レコードとして管理する。
CREATE TABLE festivals (
festival_id VARCHAR(50) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
date DATE NOT NULL,
venue_id VARCHAR(8) NOT NULL REFERENCES venues (venue_id)
);
| カラム名 | 型 | NOT NULL | 説明 |
|---|---|---|---|
festival_id |
VARCHAR(50) | ✅ | PK。例: 2025-ROCKINJAPAN-1 |
name |
VARCHAR(255) | ✅ | フェス名(例: ROCK IN JAPAN FESTIVAL 2025) |
date |
DATE | ✅ | 参加日 |
venue_id |
VARCHAR(8) | ✅ | FK → venues(venue_id) |
インデックス:
CREATE INDEX idx_festivals_venue_id ON festivals (venue_id);
CREATE INDEX idx_festivals_date ON festivals (date);
2-8. setlists(セットリスト)
ツアーまたはフェスの演奏曲目・順序を管理する(#775)。
CREATE TABLE setlists (
setlist_id VARCHAR(80) PRIMARY KEY,
type VARCHAR(10) NOT NULL,
tour_id VARCHAR(20) REFERENCES tours (tour_id) ON DELETE SET NULL,
festival_id VARCHAR(50) REFERENCES festivals (festival_id) ON DELETE SET NULL,
seq INT NOT NULL,
track_id VARCHAR(255) NOT NULL
);
| カラム名 | 型 | NOT NULL | 説明 |
|---|---|---|---|
setlist_id |
VARCHAR(80) | ✅ | PK。{tourId or festivalId}-{3桁連番}(例: T2025-01-001) |
type |
VARCHAR(10) | ✅ | 種別: tour or festival |
tour_id |
VARCHAR(20) | — | FK → tours(tour_id)。ツアーセットリストの場合に設定 |
festival_id |
VARCHAR(50) | — | FK → festivals(festival_id)。フェスセットリストの場合に設定 |
seq |
INT | ✅ | 演奏順(1始まり) |
track_id |
VARCHAR(255) | ✅ | 曲の識別子(releases.json の track ID と対応。FK 制約なし) |
備考:
tour_idとfestival_idは排他的(いずれか一方のみ設定)track_idは Blob 管理の releases.json を参照するため、DB レベルの FK 制約は設けない- 画面表示時に
track_idを releases.json で解決し、曲名・YouTube 動画 ID を取得する
インデックス:
CREATE INDEX idx_setlists_tour_id ON setlists (tour_id);
CREATE INDEX idx_setlists_festival_id ON setlists (festival_id);
3. ER 図(ライブ機能テーブル)
4. CSV 投入フォーマット(シード用)
#609(Neon スキーマ実装)でのシード投入に使用する CSV フォーマット。
venues.csv
venueId,name,prefecture,latitude,longitude
13001,日本武道館,13,35.693200,139.749700
tours.csv
tourId,title,releaseId
2026B,モーニング娘。'26 コンサートツアー春 – Rays Of Light –,
lives.csv
tourId,liveId,date,time,venueId
2026B,2026B001,2026-04-11,13:00,13002
prefecture.csv
prefecture,name
01,北海道
13,東京都
festivals.csv
festivalId,name,date,venueId
2025-SUMMERSONIC-TK,SUMMER SONIC 2025(東京),2025/8/16,11005
setlists.csv
setlistId,type,tourId,festivalId,seq,trackId
5. 設計上の注意点
prefecture フィールドの型
CHAR(2) を使用し、先頭ゼロを文字列として保持する。INTEGER や SMALLINT にすると 01 → 1 に変換されて照合が崩れる。
Blob データとの FK 制約
member_id(members.json 参照)・release_id(releases.json 参照)は Blob 管理のデータを参照するため、DB レベルの外部キー制約を設けない。整合性はアプリ層で担保する。
座標精度
DECIMAL(9,6) は整数部 3桁 + 小数部 6桁で、精度 約 0.11m(11cm)。react-leaflet での表示用途に十分。PostGIS 導入は不要。
6. 更新履歴
| 版 | 更新日 | 変更内容 | 関連 Issue |
|---|---|---|---|
| 1.3 | 2026-05-09 | setlists テーブル定義を実装仕様に更新(tour_id・festival_id FK、track_id 参照) |
#775 |
| 1.2 | 2026-05-08 | festivals テーブル定義を追加 |
#776 |
| 1.1 | 2026-04-11 | lives.time の 00:00 = 時刻不明仕様を明記 |
#528 |
| 1.0 | 2026-04-11 | 初版作成 | #528 |