Horse Racing Database System screenshot
← Back to Projects

Horse Racing Database System

A full-stack database application for managing horse racing records, built with MySQL as the backend and a Python Streamlit interface as the frontend.

MySQL Python Streamlit GitHub ↗

Overview

This project implements a complete Horse Racing Database System with a relational MySQL backend and an interactive Streamlit dashboard. It was built as a database course project to practice schema design, normalization, and query writing in a domain that has rich relationships — horses, jockeys, trainers, races, and results.

The Streamlit frontend makes the database accessible without needing SQL knowledge, providing forms for data entry and visualizations for race results and standings.

Project Goals

The main goal was to practice relational database design from scratch — identifying entities, defining relationships, normalizing to 3NF, and then writing queries that actually answer real questions about the data. Wrapping it in a Streamlit UI meant the database had to be clean enough for a non-technical user to interact with it safely.

Tech Stack

  • MySQL — Relational database engine storing all horse racing data with enforced constraints and indexes.
  • Python — Application logic, database connection via mysql-connector-python, and data processing.
  • Streamlit — Rapid frontend framework for building the interactive dashboard with minimal boilerplate.
  • Pandas — Data manipulation and preparation for display tables and charts.

Features

Entity Management

The system supports full CRUD operations for all core entities: Horses, Jockeys, Trainers, Owners, Race Tracks, and Races. Each form validates input before writing to the database, preventing constraint violations.

Race Results & Standings

After entering race results, the dashboard automatically calculates standings, win rates per jockey and horse, and tracks performance trends across races. Complex SQL joins power these views without any post-processing in Python.

Advanced Queries

Several pre-built queries answer analytical questions: top-performing jockeys by season, horses with the best win rate per track, and trainer win records. These were written as stored procedures in MySQL for reusability.

Challenges

The most demanding part was the schema design. Horse racing has complex many-to-many relationships — a horse has one jockey per race, but the same horse and jockey can pair across many races. Getting the junction tables right without creating redundancy took several iterations.

Writing efficient queries for the standings view was also tricky. Early versions did too much in Python after fetching all rows; rewriting the aggregations as SQL subqueries made the dashboard noticeably faster.

Learning and Takeaways

Database normalization is not just a theoretical exercise — every shortcut in the schema shows up later as a painful query or a data integrity bug. This project made that lesson very concrete.

Streamlit also surprised me with how quickly it can produce a usable interface. For internal tools and data projects, it completely removes the need to build a separate React or HTML frontend just to interact with a database.