This project provides optimized reporting APIs for generating sales and category reports based on MySQL 8.0. The focus was on optimizing query performance, database schema improvements, and efficient data seeding for large-scale testing.
-
Monthly Sales by Region
- Aggregates total sales and order count per region, grouped by year and month.
- Optimized for performance using indexing and schema enhancements.
-
Top Categories by Store
- Retrieves the top 10 highest-selling product categories per store.
- Utilizes MySQL's
RANK()window function for efficient ranking.
- Added appropriate indexes to speed up query performance.
- Optimized column data types for better storage efficiency.
- Ensured foreign keys and constraints were properly defined to maintain data integrity.
- Normalize structure by removing redundant store_storeId and product_productId in orders.
Indexes were added to frequently queried columns:
CREATE INDEX idx_order_date ON orders(order_date);
CREATE INDEX idx_store_region ON stores(region_id);
CREATE INDEX idx_product_category ON products(category_id);A seeding mechanism was implemented to generate realistic and large-scale test data. This helped in testing the efficiency of queries under high data volume.
- Seeded users, stores, products, and orders tables.
- Used bulk inserts for fast data generation.
Endpoint: GET /api/reports/monthly-sales
Parameters:
startDate(YYYY-MM-DD)endDate(YYYY-MM-DD)
Response:
[
{
"year": 2024,
"month": 1,
"region_id": 2,
"total_sales": 15000.50,
"number_of_orders": 230
}
]Endpoint: GET /api/reports/top-categories
Parameters:
startDate(YYYY-MM-DD)endDate(YYYY-MM-DD)
Response:
[
{
"store_id": 1,
"category_id": 5,
"total_sales": 32000.75,
"rank_within_store": 1
}
]Optimized query using indexes and avoiding unnecessary functions:
SELECT
YEAR(order_date) AS year,
MONTH(order_date) AS month,
s.region_id,
SUM(o.quantity * o.unit_price) AS total_sales,
COUNT(o.order_id) AS number_of_orders
FROM orders o
JOIN stores s ON o.store_id = s.store_id
WHERE o.order_date BETWEEN :startDate AND :endDate
GROUP BY year, month, region_id;Efficient ranking using RANK():
WITH ranked_categories AS (
SELECT
o.store_id,
p.category_id,
SUM(o.quantity * o.unit_price) AS total_sales,
RANK() OVER (PARTITION BY o.store_id ORDER BY SUM(o.quantity * o.unit_price) DESC) AS rank_within_store
FROM orders o
JOIN products p ON o.product_id = p.product_id
WHERE o.order_date BETWEEN :startDate AND :endDate
GROUP BY o.store_id, p.category_id
)
SELECT * FROM ranked_categories WHERE rank_within_store <= 10;- Run Migrations
php app.php migrate- Seed the Database
php app.php seed:database- Start the Server
php app.php serveThis project successfully implemented optimized queries and database improvements for efficient reporting. Future enhancements could include caching for frequently accessed reports and additional analytics features.