add brain
This commit is contained in:
@@ -0,0 +1,375 @@
|
||||
{
|
||||
"queries": [
|
||||
{
|
||||
"id": "user_login",
|
||||
"type": "SELECT",
|
||||
"table": "users",
|
||||
"description": "User authentication lookup by email",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "email",
|
||||
"operator": "=",
|
||||
"selectivity": 0.95
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [],
|
||||
"group_by": [],
|
||||
"frequency": 5000,
|
||||
"avg_execution_time_ms": 2.5
|
||||
},
|
||||
{
|
||||
"id": "product_search_category",
|
||||
"type": "SELECT",
|
||||
"table": "products",
|
||||
"description": "Product search within category with pagination",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "category_id",
|
||||
"operator": "=",
|
||||
"selectivity": 0.2
|
||||
},
|
||||
{
|
||||
"column": "is_active",
|
||||
"operator": "=",
|
||||
"selectivity": 0.1
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [
|
||||
{"column": "created_at", "direction": "DESC"}
|
||||
],
|
||||
"group_by": [],
|
||||
"frequency": 2500,
|
||||
"avg_execution_time_ms": 15.2
|
||||
},
|
||||
{
|
||||
"id": "product_search_price_range",
|
||||
"type": "SELECT",
|
||||
"table": "products",
|
||||
"description": "Product search by price range and brand",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "price",
|
||||
"operator": "BETWEEN",
|
||||
"selectivity": 0.3
|
||||
},
|
||||
{
|
||||
"column": "brand",
|
||||
"operator": "=",
|
||||
"selectivity": 0.05
|
||||
},
|
||||
{
|
||||
"column": "is_active",
|
||||
"operator": "=",
|
||||
"selectivity": 0.1
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [
|
||||
{"column": "price", "direction": "ASC"}
|
||||
],
|
||||
"group_by": [],
|
||||
"frequency": 800,
|
||||
"avg_execution_time_ms": 25.7
|
||||
},
|
||||
{
|
||||
"id": "user_orders_history",
|
||||
"type": "SELECT",
|
||||
"table": "orders",
|
||||
"description": "User order history with pagination",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "user_id",
|
||||
"operator": "=",
|
||||
"selectivity": 0.8
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [
|
||||
{"column": "created_at", "direction": "DESC"}
|
||||
],
|
||||
"group_by": [],
|
||||
"frequency": 1200,
|
||||
"avg_execution_time_ms": 8.3
|
||||
},
|
||||
{
|
||||
"id": "order_details_with_items",
|
||||
"type": "SELECT",
|
||||
"table": "orders",
|
||||
"description": "Order details with order items (JOIN query)",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "id",
|
||||
"operator": "=",
|
||||
"selectivity": 1.0
|
||||
}
|
||||
],
|
||||
"join_conditions": [
|
||||
{
|
||||
"local_column": "id",
|
||||
"foreign_table": "order_items",
|
||||
"foreign_column": "order_id",
|
||||
"join_type": "INNER"
|
||||
}
|
||||
],
|
||||
"order_by": [],
|
||||
"group_by": [],
|
||||
"frequency": 3000,
|
||||
"avg_execution_time_ms": 12.1
|
||||
},
|
||||
{
|
||||
"id": "pending_orders_processing",
|
||||
"type": "SELECT",
|
||||
"table": "orders",
|
||||
"description": "Processing queue - pending orders by date",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "status",
|
||||
"operator": "=",
|
||||
"selectivity": 0.15
|
||||
},
|
||||
{
|
||||
"column": "created_at",
|
||||
"operator": ">=",
|
||||
"selectivity": 0.3
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [
|
||||
{"column": "created_at", "direction": "ASC"}
|
||||
],
|
||||
"group_by": [],
|
||||
"frequency": 150,
|
||||
"avg_execution_time_ms": 45.2
|
||||
},
|
||||
{
|
||||
"id": "user_orders_by_status",
|
||||
"type": "SELECT",
|
||||
"table": "orders",
|
||||
"description": "User orders filtered by status",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "user_id",
|
||||
"operator": "=",
|
||||
"selectivity": 0.8
|
||||
},
|
||||
{
|
||||
"column": "status",
|
||||
"operator": "IN",
|
||||
"selectivity": 0.4
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [
|
||||
{"column": "created_at", "direction": "DESC"}
|
||||
],
|
||||
"group_by": [],
|
||||
"frequency": 600,
|
||||
"avg_execution_time_ms": 18.5
|
||||
},
|
||||
{
|
||||
"id": "product_reviews_summary",
|
||||
"type": "SELECT",
|
||||
"table": "product_reviews",
|
||||
"description": "Product review aggregation",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "product_id",
|
||||
"operator": "=",
|
||||
"selectivity": 0.85
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [],
|
||||
"group_by": ["product_id"],
|
||||
"frequency": 1800,
|
||||
"avg_execution_time_ms": 22.3
|
||||
},
|
||||
{
|
||||
"id": "inventory_low_stock",
|
||||
"type": "SELECT",
|
||||
"table": "products",
|
||||
"description": "Low inventory alert query",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "inventory_count",
|
||||
"operator": "<=",
|
||||
"selectivity": 0.1
|
||||
},
|
||||
{
|
||||
"column": "is_active",
|
||||
"operator": "=",
|
||||
"selectivity": 0.1
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [
|
||||
{"column": "inventory_count", "direction": "ASC"}
|
||||
],
|
||||
"group_by": [],
|
||||
"frequency": 50,
|
||||
"avg_execution_time_ms": 35.8
|
||||
},
|
||||
{
|
||||
"id": "popular_products_by_category",
|
||||
"type": "SELECT",
|
||||
"table": "order_items",
|
||||
"description": "Popular products analysis with category join",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "created_at",
|
||||
"operator": ">=",
|
||||
"selectivity": 0.2
|
||||
}
|
||||
],
|
||||
"join_conditions": [
|
||||
{
|
||||
"local_column": "product_id",
|
||||
"foreign_table": "products",
|
||||
"foreign_column": "id",
|
||||
"join_type": "INNER"
|
||||
},
|
||||
{
|
||||
"local_column": "category_id",
|
||||
"foreign_table": "categories",
|
||||
"foreign_column": "id",
|
||||
"join_type": "INNER"
|
||||
}
|
||||
],
|
||||
"order_by": [
|
||||
{"column": "total_quantity", "direction": "DESC"}
|
||||
],
|
||||
"group_by": ["product_id", "category_id"],
|
||||
"frequency": 25,
|
||||
"avg_execution_time_ms": 180.5
|
||||
},
|
||||
{
|
||||
"id": "customer_purchase_history",
|
||||
"type": "SELECT",
|
||||
"table": "orders",
|
||||
"description": "Customer analytics - purchase history with items",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "user_id",
|
||||
"operator": "=",
|
||||
"selectivity": 0.8
|
||||
},
|
||||
{
|
||||
"column": "status",
|
||||
"operator": "IN",
|
||||
"selectivity": 0.6
|
||||
}
|
||||
],
|
||||
"join_conditions": [
|
||||
{
|
||||
"local_column": "id",
|
||||
"foreign_table": "order_items",
|
||||
"foreign_column": "order_id",
|
||||
"join_type": "INNER"
|
||||
}
|
||||
],
|
||||
"order_by": [
|
||||
{"column": "created_at", "direction": "DESC"}
|
||||
],
|
||||
"group_by": [],
|
||||
"frequency": 300,
|
||||
"avg_execution_time_ms": 65.2
|
||||
},
|
||||
{
|
||||
"id": "daily_sales_report",
|
||||
"type": "SELECT",
|
||||
"table": "orders",
|
||||
"description": "Daily sales aggregation report",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "created_at",
|
||||
"operator": ">=",
|
||||
"selectivity": 0.05
|
||||
},
|
||||
{
|
||||
"column": "status",
|
||||
"operator": "IN",
|
||||
"selectivity": 0.6
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [
|
||||
{"column": "order_date", "direction": "DESC"}
|
||||
],
|
||||
"group_by": ["DATE(created_at)"],
|
||||
"frequency": 10,
|
||||
"avg_execution_time_ms": 250.8
|
||||
},
|
||||
{
|
||||
"id": "category_hierarchy_nav",
|
||||
"type": "SELECT",
|
||||
"table": "categories",
|
||||
"description": "Category navigation - parent-child relationships",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "parent_id",
|
||||
"operator": "=",
|
||||
"selectivity": 0.2
|
||||
},
|
||||
{
|
||||
"column": "is_active",
|
||||
"operator": "=",
|
||||
"selectivity": 0.1
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [
|
||||
{"column": "sort_order", "direction": "ASC"}
|
||||
],
|
||||
"group_by": [],
|
||||
"frequency": 800,
|
||||
"avg_execution_time_ms": 5.1
|
||||
},
|
||||
{
|
||||
"id": "recent_user_reviews",
|
||||
"type": "SELECT",
|
||||
"table": "product_reviews",
|
||||
"description": "Recent product reviews by user",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "user_id",
|
||||
"operator": "=",
|
||||
"selectivity": 0.95
|
||||
}
|
||||
],
|
||||
"join_conditions": [
|
||||
{
|
||||
"local_column": "product_id",
|
||||
"foreign_table": "products",
|
||||
"foreign_column": "id",
|
||||
"join_type": "INNER"
|
||||
}
|
||||
],
|
||||
"order_by": [
|
||||
{"column": "created_at", "direction": "DESC"}
|
||||
],
|
||||
"group_by": [],
|
||||
"frequency": 200,
|
||||
"avg_execution_time_ms": 12.7
|
||||
},
|
||||
{
|
||||
"id": "product_avg_rating",
|
||||
"type": "SELECT",
|
||||
"table": "product_reviews",
|
||||
"description": "Product average rating calculation",
|
||||
"where_conditions": [
|
||||
{
|
||||
"column": "product_id",
|
||||
"operator": "IN",
|
||||
"selectivity": 0.1
|
||||
}
|
||||
],
|
||||
"join_conditions": [],
|
||||
"order_by": [],
|
||||
"group_by": ["product_id"],
|
||||
"frequency": 400,
|
||||
"avg_execution_time_ms": 35.4
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
{
|
||||
"tables": {
|
||||
"users": {
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 50000
|
||||
},
|
||||
"email": {
|
||||
"type": "VARCHAR(255)",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 50000
|
||||
},
|
||||
"username": {
|
||||
"type": "VARCHAR(50)",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 50000
|
||||
},
|
||||
"password_hash": {
|
||||
"type": "VARCHAR(255)",
|
||||
"nullable": false,
|
||||
"cardinality_estimate": 50000
|
||||
},
|
||||
"first_name": {
|
||||
"type": "VARCHAR(100)",
|
||||
"nullable": true,
|
||||
"cardinality_estimate": 25000
|
||||
},
|
||||
"last_name": {
|
||||
"type": "VARCHAR(100)",
|
||||
"nullable": true,
|
||||
"cardinality_estimate": 30000
|
||||
},
|
||||
"status": {
|
||||
"type": "VARCHAR(20)",
|
||||
"nullable": false,
|
||||
"default": "active",
|
||||
"cardinality_estimate": 5
|
||||
},
|
||||
"created_at": {
|
||||
"type": "TIMESTAMP",
|
||||
"nullable": false,
|
||||
"default": "CURRENT_TIMESTAMP"
|
||||
}
|
||||
},
|
||||
"primary_key": ["id"],
|
||||
"unique_constraints": [
|
||||
["email"],
|
||||
["username"]
|
||||
],
|
||||
"check_constraints": {
|
||||
"chk_status_valid": "status IN ('active', 'inactive', 'suspended', 'deleted')"
|
||||
},
|
||||
"indexes": [
|
||||
{
|
||||
"name": "idx_users_email",
|
||||
"columns": ["email"],
|
||||
"unique": true
|
||||
},
|
||||
{
|
||||
"name": "idx_users_status",
|
||||
"columns": ["status"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"products": {
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 10000
|
||||
},
|
||||
"name": {
|
||||
"type": "VARCHAR(255)",
|
||||
"nullable": false,
|
||||
"cardinality_estimate": 9500
|
||||
},
|
||||
"sku": {
|
||||
"type": "VARCHAR(50)",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 10000
|
||||
},
|
||||
"price": {
|
||||
"type": "DECIMAL(10,2)",
|
||||
"nullable": false,
|
||||
"cardinality_estimate": 5000
|
||||
},
|
||||
"category_id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"foreign_key": "categories.id",
|
||||
"cardinality_estimate": 50
|
||||
},
|
||||
"brand": {
|
||||
"type": "VARCHAR(100)",
|
||||
"nullable": true,
|
||||
"cardinality_estimate": 200
|
||||
},
|
||||
"is_active": {
|
||||
"type": "BOOLEAN",
|
||||
"nullable": false,
|
||||
"default": true,
|
||||
"cardinality_estimate": 2
|
||||
},
|
||||
"inventory_count": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"default": 0,
|
||||
"cardinality_estimate": 1000
|
||||
},
|
||||
"created_at": {
|
||||
"type": "TIMESTAMP",
|
||||
"nullable": false,
|
||||
"default": "CURRENT_TIMESTAMP"
|
||||
}
|
||||
},
|
||||
"primary_key": ["id"],
|
||||
"unique_constraints": [
|
||||
["sku"]
|
||||
],
|
||||
"check_constraints": {
|
||||
"chk_price_positive": "price > 0",
|
||||
"chk_inventory_non_negative": "inventory_count >= 0"
|
||||
},
|
||||
"indexes": [
|
||||
{
|
||||
"name": "idx_products_category",
|
||||
"columns": ["category_id"]
|
||||
},
|
||||
{
|
||||
"name": "idx_products_brand",
|
||||
"columns": ["brand"]
|
||||
},
|
||||
{
|
||||
"name": "idx_products_price",
|
||||
"columns": ["price"]
|
||||
},
|
||||
{
|
||||
"name": "idx_products_active_category",
|
||||
"columns": ["is_active", "category_id"],
|
||||
"partial_condition": "is_active = true"
|
||||
}
|
||||
]
|
||||
},
|
||||
"orders": {
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 200000
|
||||
},
|
||||
"order_number": {
|
||||
"type": "VARCHAR(50)",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 200000
|
||||
},
|
||||
"user_id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"foreign_key": "users.id",
|
||||
"cardinality_estimate": 40000
|
||||
},
|
||||
"status": {
|
||||
"type": "VARCHAR(50)",
|
||||
"nullable": false,
|
||||
"default": "pending",
|
||||
"cardinality_estimate": 8
|
||||
},
|
||||
"total_amount": {
|
||||
"type": "DECIMAL(10,2)",
|
||||
"nullable": false,
|
||||
"cardinality_estimate": 50000
|
||||
},
|
||||
"payment_method": {
|
||||
"type": "VARCHAR(50)",
|
||||
"nullable": true,
|
||||
"cardinality_estimate": 10
|
||||
},
|
||||
"created_at": {
|
||||
"type": "TIMESTAMP",
|
||||
"nullable": false,
|
||||
"default": "CURRENT_TIMESTAMP"
|
||||
},
|
||||
"shipped_at": {
|
||||
"type": "TIMESTAMP",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"primary_key": ["id"],
|
||||
"unique_constraints": [
|
||||
["order_number"]
|
||||
],
|
||||
"check_constraints": {
|
||||
"chk_total_positive": "total_amount > 0",
|
||||
"chk_status_valid": "status IN ('pending', 'processing', 'shipped', 'delivered', 'cancelled')"
|
||||
},
|
||||
"indexes": [
|
||||
{
|
||||
"name": "idx_orders_user",
|
||||
"columns": ["user_id"]
|
||||
},
|
||||
{
|
||||
"name": "idx_orders_status",
|
||||
"columns": ["status"]
|
||||
},
|
||||
{
|
||||
"name": "idx_orders_created",
|
||||
"columns": ["created_at"]
|
||||
},
|
||||
{
|
||||
"name": "idx_orders_user_status",
|
||||
"columns": ["user_id", "status"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"order_items": {
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 800000
|
||||
},
|
||||
"order_id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"foreign_key": "orders.id",
|
||||
"cardinality_estimate": 200000
|
||||
},
|
||||
"product_id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"foreign_key": "products.id",
|
||||
"cardinality_estimate": 8000
|
||||
},
|
||||
"quantity": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"cardinality_estimate": 20
|
||||
},
|
||||
"unit_price": {
|
||||
"type": "DECIMAL(10,2)",
|
||||
"nullable": false,
|
||||
"cardinality_estimate": 5000
|
||||
},
|
||||
"total_price": {
|
||||
"type": "DECIMAL(10,2)",
|
||||
"nullable": false,
|
||||
"cardinality_estimate": 10000
|
||||
}
|
||||
},
|
||||
"primary_key": ["id"],
|
||||
"check_constraints": {
|
||||
"chk_quantity_positive": "quantity > 0",
|
||||
"chk_unit_price_positive": "unit_price > 0"
|
||||
},
|
||||
"indexes": [
|
||||
{
|
||||
"name": "idx_order_items_order",
|
||||
"columns": ["order_id"]
|
||||
},
|
||||
{
|
||||
"name": "idx_order_items_product",
|
||||
"columns": ["product_id"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"categories": {
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 100
|
||||
},
|
||||
"name": {
|
||||
"type": "VARCHAR(100)",
|
||||
"nullable": false,
|
||||
"cardinality_estimate": 100
|
||||
},
|
||||
"parent_id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": true,
|
||||
"foreign_key": "categories.id",
|
||||
"cardinality_estimate": 20
|
||||
},
|
||||
"is_active": {
|
||||
"type": "BOOLEAN",
|
||||
"nullable": false,
|
||||
"default": true,
|
||||
"cardinality_estimate": 2
|
||||
}
|
||||
},
|
||||
"primary_key": ["id"],
|
||||
"indexes": [
|
||||
{
|
||||
"name": "idx_categories_parent",
|
||||
"columns": ["parent_id"]
|
||||
},
|
||||
{
|
||||
"name": "idx_categories_active",
|
||||
"columns": ["is_active"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"product_reviews": {
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"unique": true,
|
||||
"cardinality_estimate": 150000
|
||||
},
|
||||
"product_id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"foreign_key": "products.id",
|
||||
"cardinality_estimate": 8000
|
||||
},
|
||||
"user_id": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"foreign_key": "users.id",
|
||||
"cardinality_estimate": 30000
|
||||
},
|
||||
"rating": {
|
||||
"type": "INTEGER",
|
||||
"nullable": false,
|
||||
"cardinality_estimate": 5
|
||||
},
|
||||
"review_text": {
|
||||
"type": "TEXT",
|
||||
"nullable": true
|
||||
},
|
||||
"created_at": {
|
||||
"type": "TIMESTAMP",
|
||||
"nullable": false,
|
||||
"default": "CURRENT_TIMESTAMP"
|
||||
}
|
||||
},
|
||||
"primary_key": ["id"],
|
||||
"unique_constraints": [
|
||||
["product_id", "user_id"]
|
||||
],
|
||||
"check_constraints": {
|
||||
"chk_rating_valid": "rating BETWEEN 1 AND 5"
|
||||
},
|
||||
"indexes": [
|
||||
{
|
||||
"name": "idx_reviews_product",
|
||||
"columns": ["product_id"]
|
||||
},
|
||||
{
|
||||
"name": "idx_reviews_user",
|
||||
"columns": ["user_id"]
|
||||
},
|
||||
{
|
||||
"name": "idx_reviews_rating",
|
||||
"columns": ["rating"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
-- Sample E-commerce Database Schema
|
||||
-- Demonstrates various normalization levels and common patterns
|
||||
|
||||
-- Users table - well normalized
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
first_name VARCHAR(100),
|
||||
last_name VARCHAR(100),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
status VARCHAR(20) DEFAULT 'active'
|
||||
);
|
||||
|
||||
-- Categories table - hierarchical structure
|
||||
CREATE TABLE categories (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(100) NOT NULL UNIQUE,
|
||||
parent_id INTEGER REFERENCES categories(id),
|
||||
description TEXT,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Products table - potential normalization issues
|
||||
CREATE TABLE products (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
sku VARCHAR(50) NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
price DECIMAL(10,2) NOT NULL,
|
||||
cost DECIMAL(10,2),
|
||||
weight DECIMAL(8,2),
|
||||
dimensions VARCHAR(50), -- Potential 1NF violation: "10x5x3 inches"
|
||||
category_id INTEGER REFERENCES categories(id),
|
||||
category_name VARCHAR(100), -- Redundant with categories.name (3NF violation)
|
||||
brand VARCHAR(100), -- Should be normalized to separate brands table
|
||||
tags VARCHAR(500), -- Potential 1NF violation: comma-separated tags
|
||||
inventory_count INTEGER DEFAULT 0,
|
||||
reorder_point INTEGER DEFAULT 10,
|
||||
supplier_name VARCHAR(100), -- Should be normalized
|
||||
supplier_contact VARCHAR(255), -- Should be normalized
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
featured BOOLEAN DEFAULT false,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Addresses table - good normalization
|
||||
CREATE TABLE addresses (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id),
|
||||
address_type VARCHAR(20) DEFAULT 'shipping', -- 'shipping', 'billing'
|
||||
street_address VARCHAR(255) NOT NULL,
|
||||
street_address_2 VARCHAR(255),
|
||||
city VARCHAR(100) NOT NULL,
|
||||
state VARCHAR(50) NOT NULL,
|
||||
postal_code VARCHAR(20) NOT NULL,
|
||||
country VARCHAR(50) NOT NULL DEFAULT 'US',
|
||||
is_default BOOLEAN DEFAULT false,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Orders table - mixed normalization issues
|
||||
CREATE TABLE orders (
|
||||
id INTEGER PRIMARY KEY,
|
||||
order_number VARCHAR(50) NOT NULL UNIQUE,
|
||||
user_id INTEGER REFERENCES users(id),
|
||||
user_email VARCHAR(255), -- Denormalized for performance/historical reasons
|
||||
user_name VARCHAR(200), -- Denormalized for performance/historical reasons
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'pending',
|
||||
total_amount DECIMAL(10,2) NOT NULL,
|
||||
tax_amount DECIMAL(10,2) NOT NULL,
|
||||
shipping_amount DECIMAL(10,2) NOT NULL,
|
||||
discount_amount DECIMAL(10,2) DEFAULT 0,
|
||||
payment_method VARCHAR(50), -- Should be normalized to payment_methods
|
||||
payment_status VARCHAR(50) DEFAULT 'pending',
|
||||
shipping_address_id INTEGER REFERENCES addresses(id),
|
||||
billing_address_id INTEGER REFERENCES addresses(id),
|
||||
-- Denormalized shipping address for historical preservation
|
||||
shipping_street VARCHAR(255),
|
||||
shipping_city VARCHAR(100),
|
||||
shipping_state VARCHAR(50),
|
||||
shipping_postal_code VARCHAR(20),
|
||||
shipping_country VARCHAR(50),
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
shipped_at TIMESTAMP,
|
||||
delivered_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- Order items table - properly normalized
|
||||
CREATE TABLE order_items (
|
||||
id INTEGER PRIMARY KEY,
|
||||
order_id INTEGER REFERENCES orders(id),
|
||||
product_id INTEGER REFERENCES products(id),
|
||||
product_name VARCHAR(255), -- Denormalized for historical reasons
|
||||
product_sku VARCHAR(50), -- Denormalized for historical reasons
|
||||
quantity INTEGER NOT NULL,
|
||||
unit_price DECIMAL(10,2) NOT NULL,
|
||||
total_price DECIMAL(10,2) NOT NULL, -- Calculated field (could be computed)
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Shopping cart table - session-based data
|
||||
CREATE TABLE shopping_cart (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id),
|
||||
session_id VARCHAR(255), -- For anonymous users
|
||||
product_id INTEGER REFERENCES products(id),
|
||||
quantity INTEGER NOT NULL DEFAULT 1,
|
||||
added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(user_id, product_id),
|
||||
UNIQUE(session_id, product_id)
|
||||
);
|
||||
|
||||
-- Product reviews - user-generated content
|
||||
CREATE TABLE product_reviews (
|
||||
id INTEGER PRIMARY KEY,
|
||||
product_id INTEGER REFERENCES products(id),
|
||||
user_id INTEGER REFERENCES users(id),
|
||||
rating INTEGER NOT NULL CHECK (rating BETWEEN 1 AND 5),
|
||||
title VARCHAR(200),
|
||||
review_text TEXT,
|
||||
verified_purchase BOOLEAN DEFAULT false,
|
||||
helpful_count INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(product_id, user_id) -- One review per user per product
|
||||
);
|
||||
|
||||
-- Coupons table - promotional data
|
||||
CREATE TABLE coupons (
|
||||
id INTEGER PRIMARY KEY,
|
||||
code VARCHAR(50) NOT NULL UNIQUE,
|
||||
description VARCHAR(255),
|
||||
discount_type VARCHAR(20) NOT NULL, -- 'percentage', 'fixed_amount'
|
||||
discount_value DECIMAL(8,2) NOT NULL,
|
||||
minimum_amount DECIMAL(10,2),
|
||||
maximum_discount DECIMAL(10,2),
|
||||
usage_limit INTEGER,
|
||||
usage_count INTEGER DEFAULT 0,
|
||||
valid_from TIMESTAMP NOT NULL,
|
||||
valid_until TIMESTAMP NOT NULL,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Audit log table - for tracking changes
|
||||
CREATE TABLE audit_log (
|
||||
id INTEGER PRIMARY KEY,
|
||||
table_name VARCHAR(50) NOT NULL,
|
||||
record_id INTEGER NOT NULL,
|
||||
action VARCHAR(20) NOT NULL, -- 'INSERT', 'UPDATE', 'DELETE'
|
||||
old_values TEXT, -- JSON format
|
||||
new_values TEXT, -- JSON format
|
||||
user_id INTEGER REFERENCES users(id),
|
||||
ip_address VARCHAR(45),
|
||||
user_agent TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Problematic table - multiple normalization violations
|
||||
CREATE TABLE user_preferences (
|
||||
user_id INTEGER PRIMARY KEY REFERENCES users(id),
|
||||
preferred_categories VARCHAR(500), -- CSV list - 1NF violation
|
||||
email_notifications VARCHAR(255), -- "daily,weekly,promotions" - 1NF violation
|
||||
user_name VARCHAR(200), -- Redundant with users table - 3NF violation
|
||||
user_email VARCHAR(255), -- Redundant with users table - 3NF violation
|
||||
theme VARCHAR(50) DEFAULT 'light',
|
||||
language VARCHAR(10) DEFAULT 'en',
|
||||
timezone VARCHAR(50) DEFAULT 'UTC',
|
||||
currency VARCHAR(3) DEFAULT 'USD',
|
||||
date_format VARCHAR(20) DEFAULT 'YYYY-MM-DD',
|
||||
newsletter_subscribed BOOLEAN DEFAULT true,
|
||||
sms_notifications BOOLEAN DEFAULT false,
|
||||
push_notifications BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Create some basic indexes (some missing, some redundant for demonstration)
|
||||
CREATE INDEX idx_users_email ON users (email);
|
||||
CREATE INDEX idx_users_username ON users (username); -- Redundant due to UNIQUE constraint
|
||||
CREATE INDEX idx_products_category ON products (category_id);
|
||||
CREATE INDEX idx_products_brand ON products (brand);
|
||||
CREATE INDEX idx_products_sku ON products (sku); -- Redundant due to UNIQUE constraint
|
||||
CREATE INDEX idx_orders_user ON orders (user_id);
|
||||
CREATE INDEX idx_orders_status ON orders (status);
|
||||
CREATE INDEX idx_orders_created ON orders (created_at);
|
||||
CREATE INDEX idx_order_items_order ON order_items (order_id);
|
||||
CREATE INDEX idx_order_items_product ON order_items (product_id);
|
||||
-- Missing index on addresses.user_id
|
||||
-- Missing composite index on orders (user_id, status)
|
||||
-- Missing index on product_reviews.product_id
|
||||
|
||||
-- Constraints that should exist but are missing
|
||||
-- ALTER TABLE products ADD CONSTRAINT chk_price_positive CHECK (price > 0);
|
||||
-- ALTER TABLE products ADD CONSTRAINT chk_inventory_non_negative CHECK (inventory_count >= 0);
|
||||
-- ALTER TABLE order_items ADD CONSTRAINT chk_quantity_positive CHECK (quantity > 0);
|
||||
-- ALTER TABLE orders ADD CONSTRAINT chk_total_positive CHECK (total_amount > 0);
|
||||
Reference in New Issue
Block a user