CREATE TABLE IF NOT EXISTS entries ( id INTEGER PRIMARY KEY AUTOINCREMENT, event_id INTEGER NOT NULL REFERENCES events(id), category_id INTEGER NOT NULL REFERENCES event_categories(id), team_id INTEGER NOT NULL REFERENCES teams(id), athlete_id INTEGER REFERENCES athletes(id), member_names TEXT, bib TEXT, seed TEXT, status TEXT NOT NULL DEFAULT 'registered' CHECK (status IN ('registered', 'scratched', 'dq', 'dns')), remark TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), UNIQUE (category_id, team_id, athlete_id) ); CREATE INDEX IF NOT EXISTS idx_entries_event_id ON entries(event_id); CREATE INDEX IF NOT EXISTS idx_entries_team_id ON entries(team_id); CREATE INDEX IF NOT EXISTS idx_entries_athlete_id ON entries(athlete_id); CREATE INDEX IF NOT EXISTS idx_entries_category_id ON entries(category_id); -- athlete_id 为 NULL 时 UNIQUE 视为互不相等,团体项目的重复报名靠这条部分索引兜住。 CREATE UNIQUE INDEX IF NOT EXISTS idx_entries_team_unique ON entries(category_id, team_id) WHERE athlete_id IS NULL; CREATE TABLE IF NOT EXISTS results ( id INTEGER PRIMARY KEY AUTOINCREMENT, event_id INTEGER NOT NULL REFERENCES events(id), entry_id INTEGER NOT NULL UNIQUE REFERENCES entries(id), rank INTEGER CHECK (rank IS NULL OR rank >= 1), result_text TEXT, result_value REAL, unit TEXT, is_tie INTEGER NOT NULL DEFAULT 0 CHECK (is_tie IN (0, 1)), points_override REAL, status TEXT NOT NULL DEFAULT 'ok' CHECK (status IN ('ok', 'dq', 'dns', 'dnf', 'withdrawn')), state TEXT NOT NULL DEFAULT 'draft' CHECK (state IN ('draft', 'published')), -- recorded_by / verified_by 指向系统库 users,跨库不能建外键。 recorded_by INTEGER, recorded_at TEXT, verified_by INTEGER, verified_at TEXT, note TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE INDEX IF NOT EXISTS idx_results_event_state ON results(event_id, state); CREATE INDEX IF NOT EXISTS idx_results_event_rank ON results(event_id, rank);