How to design a polymorphic database schema for entities with structurally different shapes?
08:37 18 Sep 2026

I'm building a backend that stores match data across multiple sports (football, basketball, tennis, cricket, MMA, etc.). The problem is these sports have fundamentally different structures:

  • Football: 2 halves, stoppage time, running score

  • Basketball: 4 quarters, fouls that affect scoring

  • Tennis: sets, games, points (15/30/40/deuce) — not a running total

  • Cricket: innings, wickets, overs

  • MMA: rounds, no score until decision

I tried a generic match table with nullable columns for every sport, but it grew to 40+ nullable fields and every query needed sport-specific if checks.

I then tried a table-per-sport approach, but that broke the ability to query across sports uniformly.

My current approach:

  1. Shared core table with: match_id, status, started_at, competition_id, season_id

  2. Sport-specific payload stored as JSONB column with sport-dependent schema

  3. Shared API layer normalizes the response

Question: Is JSONB the right choice here, or should I use separate tables per sport with a common view? What are the tradeoffs for indexing and query performance when the JSONB fields differ per sport?

Stack: PostgreSQL 15, Node.js backend.

advice postgresql