Design E-Commerce Tables and Indexes for Recent-Spend Queries
VisaSoftware Engineer I · Online AssessmentLast updated
This question tests database schema normalization, data integrity in e-commerce transactions, and the ability to optimize SQL queries using indexing strategies.
Schema Design and Optimization
You are designing the core database schema for an e-commerce platform. The system must track users, products, orders, and order line items. A critical requirement is that when a user places an order, the price of each item must be snapshotted at that moment, as product prices change over time.
1. Schema Design
Define a normalized relational schema with the following tables:
Users:user_id(PK),email,created_at.Products:product_id(PK),current_price,stock_quantity.Orders:order_id(PK),user_id(FK),status(e.g., 'pending', 'completed'),created_at.Order_Items:item_id(PK),order_id(FK),product_id(FK),captured_price.
Explain how you ensure data consistency for captured_price and what integrity constraints you would apply to the Order_Items table.
2. Query and Indexing
Write a SQL query to calculate the total spend of each user for all completed orders placed in the last 30 days.
-- Example Target Query
SELECT user_id, SUM(captured_price) as total_spent
FROM Orders O
JOIN Order_Items OI ON O.order_id = OI.order_id
WHERE O.status = 'completed' AND O.created_at >= NOW() - INTERVAL '30 days'
GROUP BY user_id;
Propose a set of indexes to optimize this query. Provide the specific CREATE INDEX statements and explain why your chosen columns and order (column cardinality/prefixing) benefit the execution plan.
3. Evaluation
Briefly explain what you would look for in a EXPLAIN ANALYZE output to verify that your indexes are effectively reducing scan costs.
Hints
Hint 1
Consider why you must store a price in the Order_Items table rather than simply referencing the current price in the Products table.
Hint 2
For the index, consider a composite index that covers the filtering conditions in the WHERE clause first, followed by join keys.
Hint 3
Think about how an Index Range Scan on a date column might interact with the status filter and join operations.
Follow-up questions
- How would you handle the database migration if you needed to add a 'discount_code' field to the Order_Items table after the system has been live for a year?
- What are the trade-offs of using a composite index on (status, created_at) versus separate indexes for each column?
- If the number of orders per user is extremely high, how might you optimize this calculation further (e.g., materialized views or asynchronous pre-aggregation)?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.