242 lines
7.2 KiB
Markdown
242 lines
7.2 KiB
Markdown
# Database Schema
|
|
|
|
## Overview
|
|
The database uses PostgreSQL with SQLAlchemy ORM. All tables are auto-created from models.
|
|
|
|
## Tables
|
|
|
|
### users
|
|
User accounts and profile information.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | INTEGER | PRIMARY KEY | User identifier |
|
|
| email | VARCHAR | UNIQUE, INDEXED | User email |
|
|
| hashed_password | VARCHAR | NOT NULL | Bcrypt hashed password |
|
|
| full_name | VARCHAR | NOT NULL | User's full name |
|
|
| phone | VARCHAR | NULLABLE | Phone number |
|
|
| address | VARCHAR | NULLABLE | Street address |
|
|
| city | VARCHAR | NULLABLE | City |
|
|
| postal_code | VARCHAR | NULLABLE | Postal/ZIP code |
|
|
| country | VARCHAR | NULLABLE | Country |
|
|
| is_active | BOOLEAN | DEFAULT TRUE | Account status |
|
|
| created_at | DATETIME | DEFAULT NOW() | Account creation date |
|
|
|
|
### categories
|
|
Product categories.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | INTEGER | PRIMARY KEY | Category identifier |
|
|
| name | VARCHAR | UNIQUE, INDEXED | Category name |
|
|
| slug | VARCHAR | UNIQUE, INDEXED | URL-friendly slug |
|
|
| description | VARCHAR | NULLABLE | Category description |
|
|
|
|
**Predefined Categories:**
|
|
- Shoes
|
|
- Shirts
|
|
- Pants
|
|
- Hats
|
|
- Accessories
|
|
|
|
### products
|
|
Product inventory and details.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | INTEGER | PRIMARY KEY | Product identifier |
|
|
| name | VARCHAR | INDEXED | Product name |
|
|
| description | TEXT | NOT NULL | Product description |
|
|
| price | FLOAT | NOT NULL | Regular price |
|
|
| discount_price | FLOAT | NULLABLE | Sale price if on sale |
|
|
| category_id | INTEGER | FOREIGN KEY | Reference to category |
|
|
| gender | VARCHAR | NOT NULL | men/women |
|
|
| brand | VARCHAR | NOT NULL | Product brand |
|
|
| sizes | JSON | NOT NULL | Array of available sizes |
|
|
| colors | JSON | NOT NULL | Array of available colors |
|
|
| stock | INTEGER | DEFAULT 0 | Quantity available |
|
|
| images | JSON | NOT NULL | Array of image URLs |
|
|
| is_featured | BOOLEAN | DEFAULT FALSE | Featured product flag |
|
|
| is_on_sale | BOOLEAN | DEFAULT FALSE | Sale flag |
|
|
| created_at | DATETIME | DEFAULT NOW() | Product added date |
|
|
|
|
**indexes:**
|
|
- category_id (FOREIGN KEY)
|
|
|
|
### cart
|
|
User shopping carts.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | INTEGER | PRIMARY KEY | Cart identifier |
|
|
| user_id | INTEGER | FOREIGN KEY UNIQUE | Reference to user |
|
|
| created_at | DATETIME | DEFAULT NOW() | Cart creation date |
|
|
|
|
**Relationships:**
|
|
- One cart per user
|
|
- Can contain multiple cart_items
|
|
|
|
### cart_items
|
|
Items in shopping carts.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | INTEGER | PRIMARY KEY | Cart item identifier |
|
|
| cart_id | INTEGER | FOREIGN KEY | Reference to cart |
|
|
| product_id | INTEGER | FOREIGN KEY | Reference to product |
|
|
| quantity | INTEGER | DEFAULT 1 | Item quantity |
|
|
| size | VARCHAR | NULLABLE | Selected size |
|
|
| color | VARCHAR | NULLABLE | Selected color |
|
|
|
|
**Relationships:**
|
|
- Belongs to cart
|
|
- References product
|
|
|
|
### orders
|
|
Customer orders.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | INTEGER | PRIMARY KEY | Order identifier |
|
|
| user_id | INTEGER | FOREIGN KEY | Reference to user |
|
|
| order_number | VARCHAR | UNIQUE, INDEXED | Human-readable order # |
|
|
| status | VARCHAR | DEFAULT 'pending' | pending/paid/shipped/delivered |
|
|
| total_amount | FLOAT | NOT NULL | Order total |
|
|
| shipping_address | VARCHAR | NOT NULL | Shipping street |
|
|
| shipping_city | VARCHAR | NOT NULL | Shipping city |
|
|
| shipping_postal_code | VARCHAR | NOT NULL | Shipping postal code |
|
|
| shipping_country | VARCHAR | NOT NULL | Shipping country |
|
|
| created_at | DATETIME | DEFAULT NOW() | Order creation date |
|
|
| updated_at | DATETIME | DEFAULT NOW() | Last update date |
|
|
|
|
**Relationships:**
|
|
- Belongs to user
|
|
- Can contain multiple order_items
|
|
|
|
### order_items
|
|
Items in orders.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | INTEGER | PRIMARY KEY | Order item identifier |
|
|
| order_id | INTEGER | FOREIGN KEY | Reference to order |
|
|
| product_id | INTEGER | FOREIGN KEY | Reference to product |
|
|
| quantity | INTEGER | NOT NULL | Item quantity |
|
|
| price | FLOAT | NOT NULL | Price at purchase time |
|
|
| size | VARCHAR | NULLABLE | Selected size |
|
|
| color | VARCHAR | NULLABLE | Selected color |
|
|
|
|
**Note:** Price is stored to preserve historical data
|
|
|
|
### wishlist
|
|
User wishlists.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | INTEGER | PRIMARY KEY | Wishlist item identifier |
|
|
| user_id | INTEGER | FOREIGN KEY | Reference to user |
|
|
| product_id | INTEGER | FOREIGN KEY | Reference to product |
|
|
| created_at | DATETIME | DEFAULT NOW() | Added to wishlist date |
|
|
|
|
**Constraint:** UNIQUE(user_id, product_id) - one entry per user-product pair
|
|
|
|
### contact_messages
|
|
Contact form submissions.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | INTEGER | PRIMARY KEY | Message identifier |
|
|
| name | VARCHAR | NOT NULL | Sender name |
|
|
| email | VARCHAR | NOT NULL | Sender email |
|
|
| subject | VARCHAR | NOT NULL | Message subject |
|
|
| message | TEXT | NOT NULL | Message content |
|
|
| created_at | DATETIME | DEFAULT NOW() | Submission date |
|
|
|
|
## Relationships Diagram
|
|
|
|
```
|
|
users
|
|
├─ 1:1 ─→ cart
|
|
│ ├─ 1:many ─→ cart_items
|
|
│ └─ many:1 ─→ products
|
|
├─ 1:many ─→ orders
|
|
│ ├─ 1:many ─→ order_items
|
|
│ └─ many:1 ─→ products
|
|
└─ many:many ─→ products (via wishlist)
|
|
|
|
categories
|
|
└─ 1:many ─→ products
|
|
|
|
contact_messages
|
|
(standalone)
|
|
```
|
|
|
|
## Sample Data
|
|
|
|
The seed script includes:
|
|
|
|
**Categories:** 5
|
|
- Shoes, Shirts, Pants, Hats, Accessories
|
|
|
|
**Products:** 15+
|
|
- emphasis on shoes (Nike, Adidas, Cole Haan, Salomon, etc.)
|
|
- Mix of men's and women's items
|
|
- Various price points ($19.99 - $189.99)
|
|
- Sale and featured items
|
|
|
|
**Users:** 2
|
|
- user@example.com (password: password123)
|
|
- jane@example.com (password: password123)
|
|
|
|
## Indexing Strategy
|
|
|
|
Indexed columns for performance:
|
|
- users.email (UNIQUE)
|
|
- categories.name (UNIQUE)
|
|
- categories.slug (UNIQUE)
|
|
- products.name
|
|
- products.category_id
|
|
- orders.order_number (UNIQUE)
|
|
- orders.user_id
|
|
|
|
## Backup and Restore
|
|
|
|
### Backup Database
|
|
```bash
|
|
pg_dump -U postgres ecommerce_db > backup.sql
|
|
```
|
|
|
|
### Restore Database
|
|
```bash
|
|
psql -U postgres ecommerce_db < backup.sql
|
|
```
|
|
|
|
## Connection Pooling
|
|
|
|
In production, consider using a connection pool. SQLAlchemy is configured in `database.py`.
|
|
|
|
## Migration Notes
|
|
|
|
If modifying models:
|
|
1. Update the model in `app/models/`
|
|
2. Tables auto-create via `Base.metadata.create_all()`
|
|
3. For existing databases, manually ALTER TABLE
|
|
|
|
## Performance Optimization
|
|
|
|
- Indexes on frequently queried columns
|
|
- JSON columns for flexible attributes
|
|
- Pagination implemented in list queries
|
|
- EAGER loading relationships where needed
|
|
|
|
## Data Validation
|
|
|
|
- Pydantic schemas validate all input
|
|
- Email validation via EmailStr
|
|
- Price and quantity constraints
|
|
- Product stock management
|
|
|
|
## Time Zone
|
|
|
|
All timestamps are stored in UTC (datetime.utcnow())
|