nbadbArena Data Lab
Schema ReferenceHalf-Court MapFacts10 waypoints

Court Geometry

Facts & Bridges

Scouting report for the 102 fact outputs and 2 bridge tables in the nbadb warehouse

Facts & Bridges

Facts hold the possessions: the measurable events, summaries, dashboards, and specialty surfaces that answer "what happened" and "how much" across NBA games, seasons, and historical context.

Fact outputs
102
game, season, event, dashboard, and specialty measurements
Bridge tables
2
clean many-to-many connectors for crews and play participants
Best habit
Start narrow
pick the smallest grain that answers the question

This page is the scouting report, not the full scorebook. Use it to choose the right fact family, then jump to the generated Star Reference when you need exact schema-backed columns and constraints.

How to use this page

  1. Choose the smallest grain that already matches the final row you want.
  2. Only then choose the stat lens such as traditional, advanced, tracking, dashboard, or event tape.
  3. Use Relationships if the family is right but the join path is still fuzzy.

Quick navigation

Jump to section

Choose a fact family

Start with Fact families when you need the closest grain match for a player-game, team-game, event, dashboard, or league-style question.

Jump to section

Read by question

Use Read the box score by question when you already have a query shape in mind and need the quickest first table.

Jump to section

Handle many-to-many joins

Jump to Current bridge tables when officials or play participants would otherwise force repeated columns or duplicate joins.

Generated boundary

Escalate or de-escalate grain

Move up to Derived Aggregations or Analytics Views for reusable shortcuts, or down to Star Reference when the exact contract matters.

Choose the possession

Start by grain, not by stat label

If the final row should represent...First family to inspectWhy this is the safe opening move
one player in one gamefact_player_game_*The player-game family keeps the grain stable while changing only the stat lens
one team in one gamefact_team_game and team box-score factsTeam-game surfaces prevent accidental player-level duplication
one action or sequence in a gamefact_play_by_play, fact_rotation, fact_matchup, fact_win_probabilityEvent and stint facts preserve order and in-game state
one player or team season summarydashboard/profile/splits facts or agg_ tablesMany recurring season cuts already exist above atomic game grain
one specialized research rowleague dash, draft, fantasy, or history factsThese tables package niche workflows that do not fit the core game families

Fact families

Content module

Player game box scores

Start with fact_player_game_* when the question is one player in one game. Traditional, advanced, misc, hustle, and tracking variants keep that grain stable while changing the stat lens.

Content module

Team game and game-summary facts

Reach for fact_team_game, team box-score tables, quarter scoring, and four-factor surfaces when the row should represent a club's side of a game rather than an individual player.

Content module

Event tape and matchup study

fact_play_by_play, fact_rotation, fact_matchup, fact_win_probability, and fact_game_leaders cover ordered actions, stints, defensive matchups, in-game state, and headline game context.

Content module

Shot and tracking analysis

Use fact_shot_chart, fact_tracking_defense, fact_player_pt_tracking, fact_team_pt_tracking, and fact_synergy when you care about shot geography, defended attempts, tracking metrics, or play-type context.

Content module

Season and dashboard reporting

fact_player_profile, fact_player_career, fact_player_splits, fact_team_splits, fact_standings, and fact_playoff_picture already package recurring season and dashboard questions.

Content module

League and historical specialty

fact_league_dash_player_stats, fact_league_dash_team_stats, fact_league_game_finder, fact_draft, fact_team_history_detail, and fact_fantasy support discovery, leaderboards, archival work, and specialty reporting.

FamilyRepresentative tablesTypical grainBest when
Player game box scorefact_player_game_traditional, fact_player_game_advanced, fact_player_game_misc, fact_player_game_hustle, fact_player_game_trackingOne row per player-gameYou need a single-game player ledger from traditional, advanced, hustle, or tracking angles
Team game box scorefact_team_game, fact_box_score_team, fact_box_score_advanced_team, fact_team_game_hustle, fact_box_score_four_factorsOne row per team-game or team-game splitYou want club performance, quarter scoring, four factors, or team-level game detail
Event tape and matchup studyfact_play_by_play, fact_rotation, fact_matchup, fact_win_probability, fact_game_leadersEvent, stint, matchup, or in-game stateYou need sequence detail, on-floor stints, matchup defense, or live game-state context
Shot, tracking, and possession analyticsfact_shot_chart, fact_tracking_defense, fact_player_pt_tracking, fact_team_pt_tracking, fact_synergyShot, player-season, team-season, or play typeYou are studying shot quality, defended attempts, tracking metrics, or possession types
Season, profile, and dashboard surfacesfact_player_profile, fact_player_career, fact_player_splits, fact_team_splits, fact_standings, fact_playoff_picturePlayer-season, team-season, or dashboard splitYou need recurring player/team reporting without rebuilding every summary from game facts
League, discovery, and historical specialtyfact_league_dash_player_stats, fact_league_dash_team_stats, fact_league_game_finder, fact_draft, fact_team_history_detail, fact_fantasyLeague-season, draft, or specialty grainYou are building leaderboards, discovery tools, draft history, or archival research

Compare the likely first stop

When the question is really about...Best first stopCommon next move
a player's box score line in a single gamefact_player_game_traditional or sibling fact_player_game_* tablesAdd dim_player, dim_team, and dim_game
a team's side of a gamefact_team_game or team box-score variantsAdd dim_team, dim_game, and temporal dimensions
event tape, stints, or matchup defensefact_play_by_play, fact_rotation, or fact_matchupAdd lookup dimensions and bridges only as needed
shot profile or tracking contextfact_shot_chart, fact_tracking_defense, fact_player_pt_tracking, fact_team_pt_trackingAdd dim_shot_zone, dim_player, and team/game context
a repeated season leaderboard or profile cutdashboard facts first, then Derived Aggregations if a reusable rollup existsMove up instead of rebuilding from game facts

Read the box score by question

If the question sounds like...Reach forWhy
"What did this player do in that game?"fact_player_game_*The player-game family is the clearest one-row-per-player-game entry point
"How did the team perform in that game?"fact_team_game or team box-score tablesThese keep team-game measures together and join cleanly to dim_game and dim_team
"What happened on every action?"fact_play_by_playIt is the event tape, with period clock and player slots on each action
"Who was on the floor, and what happened during that stint?"fact_rotationRotation stints model check-in/check-out windows and side-specific context
"Where did the shots come from?"fact_shot_chartShot geography, zone context, and make/miss outcomes live here
"Do we already have the season summary?"season/profile/dashboard facts, then agg_ tables if neededMany repeated reporting cuts already exist before you build them yourself
Bridge connectors

Current bridge tables

Bridge table

bridge_game_official

Use this bridge to attach officiating crews to a game without repeating referee columns across every game-level fact row.

Bridge table

bridge_play_player

Use this bridge when one play involves multiple players. It fans out participant slots from play-by-play into join-friendly rows instead of forcing you to decode player columns manually.

BridgeJoin patternWhy it exists
bridge_game_officialgame_id + official_idAttaches officiating crews without repeating referee columns on every game-level row
bridge_play_playergame_id + event key + participant slot/player contextFans out play-by-play participant slots into join-friendly rows when one action involves multiple players

Many dashboard-style facts rely on discriminator columns such as detail_type, split_type, tracking_type, summary_type, context_source, or leader_type. Treat those fields as part of the logical grain, not as optional decoration.

Common watchouts

WatchoutWhy it matters
Similar names do not guarantee the same grainfact_player_game_* and team box-score families can look parallel while representing different row ownership
Dashboard facts often need discriminator columnssplit_type, detail_type, or similar fields may be required to keep rows logically unique
Bridges are not optional cleanupbridge_game_official and bridge_play_player exist specifically to prevent repeated columns and awkward multi-slot joins
A season question may already be answered above fact grainCheck Derived Aggregations or Analytics Views before rebuilding a common summary yourself

Route guidance for dense reference tables

  • Use this page to pick the family.
  • Use Relationships when you know the family but not the join lane.
  • Use Derived Aggregations when the question repeats at season or league summary grain.
  • Use Analytics Views when you want common joins already packed.
  • Use Star Reference when you need exact schema-backed columns.

Keep moving

Stay in the same possession

Keep the mental model warm with adjacent pages, section hubs, and search-friendly routes into the same topic cluster.

Section hub

On this page