-- ============================================
-- 跨境电商数据分析竞赛 - 任务二:数据库设计与管理
-- 数据库创建脚本
-- ============================================

-- 创建数据库
DROP DATABASE IF EXISTS ecommerce_analysis;
CREATE DATABASE ecommerce_analysis DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE ecommerce_analysis;

-- ============================================
-- 1. 维度表设计
-- ============================================

-- 1.1 产品维度表
DROP TABLE IF EXISTS dim_product;
CREATE TABLE dim_product (
    product_id VARCHAR(20) PRIMARY KEY COMMENT '产品编号',
    product_name VARCHAR(200) NOT NULL COMMENT '产品名称',
    category VARCHAR(50) NOT NULL COMMENT '产品类别',
    sub_category VARCHAR(50) COMMENT '产品子类别',
    product_launch_date DATE NOT NULL COMMENT '产品上架日期',
    supplier_id VARCHAR(20) COMMENT '供应商编号',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    INDEX idx_category (category),
    INDEX idx_sub_category (sub_category),
    INDEX idx_launch_date (product_launch_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='产品维度表';

-- 1.2 区域维度表
DROP TABLE IF EXISTS dim_region;
CREATE TABLE dim_region (
    region_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '区域ID',
    region VARCHAR(50) NOT NULL COMMENT '区域名称',
    country VARCHAR(50) NOT NULL COMMENT '国家名称',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    UNIQUE KEY uk_region_country (region, country),
    INDEX idx_region (region)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='区域维度表';

-- 1.3 时间维度表
DROP TABLE IF EXISTS dim_time;
CREATE TABLE dim_time (
    date_id INT PRIMARY KEY COMMENT '日期ID (YYYYMMDD)',
    date DATE NOT NULL UNIQUE COMMENT '日期',
    year INT NOT NULL COMMENT '年份',
    quarter INT NOT NULL COMMENT '季度',
    month INT NOT NULL COMMENT '月份',
    week INT NOT NULL COMMENT '周数',
    day_of_week INT NOT NULL COMMENT '星期几(1-7)',
    is_weekend BOOLEAN NOT NULL COMMENT '是否周末',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    INDEX idx_year_month (year, month),
    INDEX idx_date (date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='时间维度表';

-- 1.4 客户维度表
DROP TABLE IF EXISTS dim_customer;
CREATE TABLE dim_customer (
    customer_id VARCHAR(20) PRIMARY KEY COMMENT '客户编号',
    first_purchase_date DATE COMMENT '首次购买日期',
    total_orders INT DEFAULT 0 COMMENT '总订单数',
    total_amount DECIMAL(12,2) DEFAULT 0 COMMENT '总消费金额',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    INDEX idx_first_purchase (first_purchase_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户维度表';

-- ============================================
-- 2. 事实表设计
-- ============================================

-- 2.1 销售事实表
DROP TABLE IF EXISTS fact_sales;
CREATE TABLE fact_sales (
    order_id VARCHAR(30) PRIMARY KEY COMMENT '订单编号',
    product_id VARCHAR(20) NOT NULL COMMENT '产品编号',
    customer_id VARCHAR(20) NOT NULL COMMENT '客户编号',
    region_id INT NOT NULL COMMENT '区域ID',
    order_date_id INT NOT NULL COMMENT '订单日期ID',
    order_date DATE NOT NULL COMMENT '订单日期',
    quantity INT NOT NULL CHECK (quantity > 0) COMMENT '销售数量',
    unit_price DECIMAL(10,2) NOT NULL CHECK (unit_price > 0) COMMENT '单价(美元)',
    cost_price DECIMAL(10,2) COMMENT '成本价(美元)',
    discount_rate DECIMAL(5,4) DEFAULT 0 CHECK (discount_rate >= 0 AND discount_rate <= 1) COMMENT '折扣率',
    total_amount DECIMAL(12,2) NOT NULL COMMENT '订单金额(美元)',
    shipping_cost DECIMAL(8,2) COMMENT '运费(美元)',
    delivery_days INT CHECK (delivery_days >= 0) COMMENT '配送天数',
    is_returned BOOLEAN DEFAULT FALSE COMMENT '是否退货',
    stock_quantity INT COMMENT '库存数量',
    profit DECIMAL(12,2) COMMENT '利润',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    INDEX idx_product (product_id),
    INDEX idx_customer (customer_id),
    INDEX idx_region (region_id),
    INDEX idx_order_date (order_date),
    INDEX idx_order_date_id (order_date_id),
    FOREIGN KEY (product_id) REFERENCES dim_product(product_id),
    FOREIGN KEY (customer_id) REFERENCES dim_customer(customer_id),
    FOREIGN KEY (region_id) REFERENCES dim_region(region_id),
    FOREIGN KEY (order_date_id) REFERENCES dim_time(date_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='销售事实表';

-- ============================================
-- 3. 创建索引优化查询性能
-- ============================================

-- 复合索引:支持多维度分析
CREATE INDEX idx_product_date ON fact_sales(product_id, order_date);
CREATE INDEX idx_customer_date ON fact_sales(customer_id, order_date);
CREATE INDEX idx_region_product ON fact_sales(region_id, product_id);

-- ============================================
-- 4. 创建视图简化常用查询
-- ============================================

-- 4.1 销售明细视图
CREATE OR REPLACE VIEW v_sales_detail AS
SELECT 
    fs.order_id,
    fs.order_date,
    dp.product_id,
    dp.product_name,
    dp.category,
    dp.sub_category,
    dr.region,
    dr.country,
    dc.customer_id,
    fs.quantity,
    fs.unit_price,
    fs.discount_rate,
    fs.total_amount,
    fs.cost_price,
    fs.shipping_cost,
    fs.delivery_days,
    fs.is_returned,
    fs.profit,
    dt.year,
    dt.quarter,
    dt.month
FROM fact_sales fs
INNER JOIN dim_product dp ON fs.product_id = dp.product_id
INNER JOIN dim_region dr ON fs.region_id = dr.region_id
INNER JOIN dim_customer dc ON fs.customer_id = dc.customer_id
INNER JOIN dim_time dt ON fs.order_date_id = dt.date_id;

-- 4.2 产品销售汇总视图
CREATE OR REPLACE VIEW v_product_sales_summary AS
SELECT 
    dp.product_id,
    dp.product_name,
    dp.category,
    dp.sub_category,
    COUNT(fs.order_id) AS order_count,
    SUM(fs.quantity) AS total_quantity,
    SUM(fs.total_amount) AS total_sales,
    AVG(fs.unit_price) AS avg_price,
    SUM(fs.profit) AS total_profit,
    SUM(CASE WHEN fs.is_returned THEN 1 ELSE 0 END) AS return_count,
    SUM(CASE WHEN fs.is_returned THEN 1 ELSE 0 END) / COUNT(*) AS return_rate
FROM fact_sales fs
INNER JOIN dim_product dp ON fs.product_id = dp.product_id
GROUP BY dp.product_id, dp.product_name, dp.category, dp.sub_category;

-- 4.3 区域销售汇总视图
CREATE OR REPLACE VIEW v_region_sales_summary AS
SELECT 
    dr.region,
    dr.country,
    COUNT(fs.order_id) AS order_count,
    SUM(fs.quantity) AS total_quantity,
    SUM(fs.total_amount) AS total_sales,
    AVG(fs.total_amount) AS avg_order_amount,
    SUM(fs.profit) AS total_profit
FROM fact_sales fs
INNER JOIN dim_region dr ON fs.region_id = dr.region_id
GROUP BY dr.region, dr.country;

-- ============================================
-- 5. 数据库对象说明
-- ============================================

/*
表结构说明:
1. dim_product: 存储产品主数据,支持产品分类分析
2. dim_region: 存储区域和国家信息,支持地理维度分析
3. dim_time: 存储时间维度信息,支持时间序列分析
4. dim_customer: 存储客户信息和统计指标
5. fact_sales: 核心事实表,存储销售交易数据

索引设计:
- 主键索引:保证数据唯一性
- 外键索引:优化关联查询性能
- 复合索引:支持多维度分析查询
- 普通索引:优化常用字段查询

视图设计:
- v_sales_detail: 销售明细宽表,整合所有维度信息
- v_product_sales_summary: 产品销售汇总,便于产品分析
- v_region_sales_summary: 区域销售汇总,便于区域分析
*/
