4.9 KiB
Database Design
Summary
SQLite should become the local source of truth for historical and completed session data. The design should store both raw source payloads and normalized domain rows. Raw payloads preserve source fidelity and make reprocessing possible. Normalized rows power fast product queries, analytics, and stable Web screens.
Storage Strategy
Use two layers:
- Raw source storage.
- Preserve fetched payloads exactly enough to reprocess later.
- Track source, endpoint/topic, parameters, fetch time, status, and errors.
- Normalized domain tables.
- Queryable application data keyed by F1 identifiers.
- Built from successful source payloads.
- Safe to upsert idempotently.
Raw Payload Tables
Candidate tables:
-
source_payloadsidsourceresourcerequest_keyurl_or_topicparams_jsonpayload_jsonfetched_atstatuserrorschema_version
-
ingestion_runsidscope_typescope_keystarted_atfinished_atstatusrefreshsummary_json
-
ingestion_itemsidrun_iddatasetmeeting_keysession_keystatussourcestarted_atfinished_aterror
Normalized Domain Tables
Core calendar/session tables:
meetingssessionscircuits
Participant tables:
driverssession_driversteamsor team snapshots by season/session.
Classification and standings:
session_resultsstarting_gridsdriver_championship_standingsconstructor_championship_standings
Race/session analysis:
lapsstintspit_stopspositionsintervalsrace_control_messagesweather_samplesovertakes
Telemetry and spatial data:
car_data_sampleslocation_samplestrack_outlines
Media metadata:
team_radio_messages
Derived/read-model candidates:
session_dataset_statusrace_key_momentsdriver_session_summariesrace_lap_snapshots
Derived tables should be added only when query cost or UI complexity justifies them. Start with normalized source tables and build read models in Go unless performance argues otherwise.
Provenance and Freshness
Each normalized dataset should be traceable to source ingestion metadata.
Track:
- Source: OpenF1, SignalR, static archive, manual, cache.
- First ingested time.
- Last ingested time.
- Last successful refresh.
- Last error.
- Completion status.
- Whether stale fallback was used.
This metadata supports the Data Library screen and makes partial data honest.
Immutability Policy
Completed historical sessions:
- Treat as immutable after successful ingestion.
- Do not refetch unless
--refreshis explicitly requested. - Allow reprocessing from raw payloads if schema or read models change.
Current/future sessions:
- Treat as refreshable.
- Allow opportunistic metadata fetches.
- Avoid high-volume refreshes without explicit action.
Live sessions:
- SignalR is authoritative for live state.
- Persist live data as an append-only event/snapshot stream after the live bridge is extracted.
- Keep live data separate from normalized post-session OpenF1 records until reconciliation is designed.
- Treat live data as the record of what was seen during the session, not as the corrected final historical truth.
Migration And File Layout
The current project already creates a SQLite cache database for raw HTTP responses. The domain database should be introduced without breaking that cache.
Default stance:
- Existing cache tables are infrastructure, not product domain state.
- New domain tables should be owned by
internal/store. - A separate domain DB file is the lower-risk first implementation unless a schema design pass shows strong reasons to reuse the same file.
- If the same file is reused, domain tables must be namespaced clearly and
migrations must avoid touching the current
cachetable except through deliberate cache work. - Do not auto-migrate URL-keyed cache entries into domain rows.
- Use explicit ingestion to populate the new domain tables.
High-Volume Data
High-volume tables need careful indexing and retention decisions:
car_data_sampleslocation_samplespositionsintervalslapsfor full-season analysis
Initial policy:
- Ingest high-volume telemetry only when explicitly requested.
- Keep Race Hub v1 focused on results, strategy, laps, race control, weather, positions, and track outlines.
Research Questions
- Exact indexes for Race Hub, Live Replay, Driver Explorer, and Standings.
- Whether
positionsandintervalsshould be downsampled or stored in full. - Whether
car_data_samplesandlocation_samplesshould be optional datasets. - How to map official F1 static archive sessions to OpenF1
session_key. - Whether to use SQLite FTS for race-control/team-radio search.
- How to version schema migrations without adding unnecessary framework weight.