I am a math tutor currently helping middle and high school students master common math concepts, and getting them prepared for the SAT and ACT tests.
I am also a computer programming enthusiast, especially interested in data analytics using Python, SQL and R.
I previously worked in international marketing and product development for Stanley Black & Decker, for more than 25 years.
👋 Contact me at mario@mariosanchez.org.
Made with: SQLite
Video overview: (https://youtu.be/0tICUfe6Nbg)
The database for the Soccer Shirt Store includes all entities necessary to facilitate the process of tracking customer orders and inventory available for a chain of sports retail stores that for now only sells soccer shirts. It also enables the generation of useful reports to run the business, as detailed in the queries.sql
file. As such, included in the database’s scope is:
As a result of many-to-many relationships between the Stores and Shirts, and Orders and Shirts entities, the following junction tables will be created:
This database will support:
Note that in this iteration, the system will not support automatic replenishment of shirts once inventory reaches 0.
Entities are captured in SQLite tables with the following schema.
The database includes the following entities:
The stores
table includes:
id
, which specifies the unique ID for the store as an INTEGER
. This column thus has the PRIMARY KEY
constraint applied.location
, which specifies the city or region where the store is located as TEXT
, given TEXT
is appropriate for city fields.The shirts
table includes:
id
, which specifies the unique ID for the shirt as an INTEGER
. This column thus has the PRIMARY KEY
constraint applied.team
, which specifies the shirt’s team as TEXT
.size
, which specifies the shirt size (S, M or L) as TEXT
.price
, which specifies the shirt price as NUMERIC
.All columns in the shirts
table are required and hence should have the NOT NULL
constraint applied. No other constraints are necessary.
The customer
table includes:
id
, which specifies the unique ID for the customer as an INTEGER
. This column thus has the PRIMARY KEY
constraint applied.first_name
, which specifies the customer’s first name as TEXT
, given TEXT
is appropriate for name fields.last_name
, which specifies the customer’s last name as TEXT
, given TEXT
is appropriate for name fields.All columns that are not primary keys or foreign keys in the customers
table are required, and hence should have the NOT NULL
constraint applied. No other constraints are necessary.
The salespersons
table includes:
id
, which specifies the unique ID for the salesperson as an INTEGER
. This column thus has the PRIMARY KEY
constraint applied.first_name
, which specifies the salesperson’s first name as TEXT
, given TEXT
is appropriate for name fields.last_name
, which specifies the salesperson’s last name as TEXT
, given TEXT
is appropriate for name fields.store_id
, which specifies the store the salesperson works at, as INTEGER
.All columns that are not primary keys or foreign keys in the salespersons
table are required, and hence should have the NOT NULL
constraint applied. This column store_id
has the FOREIGN KEY
constraint applied, referencing the id
column in the stores
table, which reflects and ensures that each salesperson works in a particular store.
The orders
table includes:
id
, which specifies the unique ID for the order as an INTEGER
. This column thus has the PRIMARY KEY
constraint applied.customer_id
, which specifies the ID of the customer who placed the order as an INTEGER
. This column thus has the FOREIGN KEY
constraint applied, referencing the id
column in the customers
table, which ensures that each order be referenced back to a customer.salesperson_id
, which specifies the ID of the salesperson who sold the order as an INTEGER
. This column thus has the FOREIGN KEY
constraint applied, referencing the id
column in the salespersons
table, which ensures that each order be referenced back to a salesperson.store_id
, which specifies the ID of the store where the shirt was sold, as an INTEGER
. This column thus has the FOREIGN KEY
constraint applied, referencing the id
column in the stores
table, which ensures that each order be referenced back to a store.type
, which specifies the type of order (P or R, for “purchase” or “return”) as TEXT
.date
, which specifies the date of the order, as NUMERIC
. If no value is provided, it will default to the CURRENT_TIMESTAMP.All columns that are not primary keys or foreign keys in the orders
table are required and hence have the NOT NULL
constraint applied.
The ordered
table includes:
order_id
, which specifies the ID of the order where the shirt was included, as an INTEGER
. This column thus has the FOREIGN KEY
constraint applied, referencing the id
column in the orders
table.shirt_id
, which specifies the ID of a shirt in an order, as an INTEGER
. This column thus has the FOREIGN KEY
constraint applied, referencing the id
column in the shirts
table.quantity
, which specifies quantity of shirts of each kind ordered, as an INTEGER
. Since an order can be created for a purchase or for a return, quantity
accepts negative values.The PRIMARY KEY
will be the combination of (order_id
, shirt_id
).
The carried
table includes:
store_id
, which specifies the ID of the store where the order originates, as an INTEGER
. This column thus has the FOREIGN KEY
constraint applied, referencing the id
column in the stores
table.shirt_id
, which specifies the ID of a shirt carried in the store, as an INTEGER
. This column thus has the FOREIGN KEY
constraint applied, referencing the id
column in the shirts
table.quantity
, which specifies quantity of shirts of each kind ordered, as an INTEGER
. Since an order can be created for a purchase or for a return, quantity
accepts negative values.The PRIMARY KEY
will be the combination of (store_id
, shirt_id
).
The below entity relationship diagram describes the relationships among the entities in the database.
As detailed by the diagram:
Per the typical queries in queries.sql
, it is common for users of the database to want to obtain reports based on a certain shirt being ordered. For that reason, indexes are created on the order_id
and shirt_id
on the ordered
table so that those reports are obtained faster.
Similarly, it is also common practice for a user of the database to concerned with viewing orders and sales per customer, or orders and sales to one particular customer. As such, an index is created on the customer_id
column in the orders
table to speed the identification of customers.
The current schema includes a trigger to automatically update inventory every time a shirt is sold. In order to avoid out-of-stock situations, our trigger uses a CASE statement that automatically replenishes the stock to 5 if a customer orders a quantity of shirts larger than the inventory on hand. In other words, if a store has 3 shirts in stock but the customer wants to buy 5, the store automatically orders 8 shirts: 3 to send to the customer (so the order is honored) and 5 to keep in inventory. We assume instant delivery of those 8 shirts, which in real life probably won’t be possible: a real life scenario would probably involve notifying the customer of the out-of-stock situation, asking them to come back after a few days to allow for delivery time of the replenishment order.
© 2025 Mario Sanchez Carrion