CAPACITY NOTES
Match events by ID, never by team name
Team names are display strings and they change. Key your odds store on the event ID, treat names as attributes, and log every rename you see.
A team name is a label, not an identity. Clubs rebrand, sponsors rotate through league names, and the feed's spelling of a team can change between two polls. If your storage joins on the name string, a rename looks like two different teams and your history splits in half. The fix is to key everything on the event ID and treat every name as an attribute that may change.
The event ID is the only stable handle
The storage guide designs the events table around event_id, with league, home, away and starts stored beside it, updated when the start time or the status changes, checked 2026-10-05. That layout already encodes the rule: the ID identifies the event; everything else describes it. A name that arrives different tomorrow is an update to the description, not a new event.
Follow the same rule inside your own tables. Every price row, every alert record and every cached snapshot should carry the event ID as its join key and nothing else.
Where name matching breaks
Name matching fails in three predictable ways. The cosmetic rename: a sponsor swap turns one string into another overnight, and your dedupe sees a new match. The locale drift: a feed normalizes an accented name to plain ASCII, and your stored copy now disagrees with the feed's. The collision: two clubs share a shortened name, and on the weekend both play, your join picks one at random.
All three are silent. Nothing throws an error; the history just quietly forks, and you find out weeks later when a query counts one team as two.
Log the rename, do not fight it
When the same event ID arrives with a different name string, update the stored attributes and write one log line: old value, new value, the ID. That log is your audit trail for every identity question later, and it turns a silent fork into a reviewed change.
The same habit applies downstream. Display code should always read names from the event record, never from a hardcoded list, because the record is the one place that tracks the feed's current spelling.
One exception worth a manual check
An ID you have never seen is not automatically a rename; it is usually a genuinely new event. Postponed matches re-entering the board and rescheduled fixtures can arrive with new IDs. When a new ID appears where an old one vanished with the same teams and a moved start time, link them by hand in the events table and note it, because that join is a judgment, not a rule.
IDs for identity, names for display, and a log line for every rename. Then a rebranding is a Tuesday, not a data migration.