# 数据库索引设计文档

## 1. 概述

本文档详细描述了 Crawlful Hub 系统的数据库索引设计，包括索引类型、创建策略、使用建议和性能优化方案。合理的索引设计对于提高系统查询性能、减少数据库负载至关重要。

## 2. 索引设计原则

### 2.1 设计原则

1. **选择性原则**：索引应该建立在选择性高的列上，即列值分布均匀，不同值的数量多
2. **查询频率原则**：优先为频繁查询的列创建索引
3. **覆盖查询原则**：尽量创建覆盖查询的复合索引
4. **空间与时间平衡**：权衡索引带来的查询性能提升与存储空间增加
5. **避免过度索引**：过多的索引会增加写操作的开销

### 2.2 索引类型

| 索引类型 | 描述 | 适用场景 |
|----------|------|----------|
| 主键索引 | 唯一且非空的聚集索引 | 主键查询 |
| 唯一索引 | 确保列值唯一的索引 | 唯一性约束 |
| 普通索引 | 基本索引类型 | 一般查询条件 |
| 复合索引 | 多列组合的索引 | 多列条件查询 |
| 全文索引 | 全文搜索索引 | 文本搜索 |
| 空间索引 | 地理空间数据索引 | 地理位置查询 |

## 3. 核心表索引设计

### 3.1 租户表 (cf_tenant)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询租户 |
| idx_tenant_domain | 唯一索引 | `domain` | 域名唯一约束 | 通过域名查询租户 |
| idx_tenant_status | 普通索引 | `status` | 状态筛选 | 按状态查询租户 |
| idx_tenant_name | 普通索引 | `name` | 名称搜索 | 通过名称查询租户 |
| idx_tenant_contact_email | 唯一索引 | `contact_email` | 邮箱唯一约束 | 通过邮箱查询租户 |

### 3.2 店铺表 (cf_shop)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询店铺 |
| idx_shop_tenant_id | 普通索引 | `tenant_id` | 租户关联 | 查询租户的所有店铺 |
| idx_shop_platform_shop_id | 唯一索引 | `(platform, platform_shop_id)` | 平台店铺ID唯一 | 通过平台和店铺ID查询 |
| idx_shop_status | 普通索引 | `status` | 状态筛选 | 按状态查询店铺 |
| idx_shop_platform | 普通索引 | `platform` | 平台筛选 | 按平台查询店铺 |

### 3.3 用户表 (cf_user)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询用户 |
| idx_user_tenant_id | 普通索引 | `tenant_id` | 租户关联 | 查询租户的所有用户 |
| idx_user_username | 唯一索引 | `username` | 用户名唯一 | 通过用户名登录 |
| idx_user_email | 唯一索引 | `email` | 邮箱唯一 | 通过邮箱查询用户 |
| idx_user_role | 普通索引 | `role` | 角色筛选 | 按角色查询用户 |
| idx_user_status | 普通索引 | `status` | 状态筛选 | 按状态查询用户 |

### 3.4 商品表 (cf_product)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询商品 |
| idx_product_tenant_id | 普通索引 | `tenant_id` | 租户关联 | 查询租户的所有商品 |
| idx_product_shop_id | 普通索引 | `shop_id` | 店铺关联 | 查询店铺的所有商品 |
| idx_product_platform_product_id | 唯一索引 | `(platform, product_id)` | 平台商品ID唯一 | 通过平台和商品ID查询 |
| idx_product_category | 普通索引 | `category` | 分类筛选 | 按分类查询商品 |
| idx_product_brand | 普通索引 | `brand` | 品牌筛选 | 按品牌查询商品 |
| idx_product_status | 普通索引 | `status` | 状态筛选 | 按状态查询商品 |
| idx_product_price | 普通索引 | `price` | 价格排序 | 价格范围查询 |
| idx_product_stock | 普通索引 | `stock` | 库存筛选 | 库存状态查询 |
| idx_product_shop_category | 复合索引 | `(shop_id, category, status)` | 店铺分类状态查询 | 店铺内分类商品查询 |

### 3.5 订单表 (cf_order)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询订单 |
| idx_order_tenant_id | 普通索引 | `tenant_id` | 租户关联 | 查询租户的所有订单 |
| idx_order_shop_id | 普通索引 | `shop_id` | 店铺关联 | 查询店铺的所有订单 |
| idx_order_platform_order_id | 唯一索引 | `(platform, platform_order_id)` | 平台订单ID唯一 | 通过平台和订单ID查询 |
| idx_order_status | 普通索引 | `status` | 状态筛选 | 按状态查询订单 |
| idx_order_customer_id | 普通索引 | `customer_id` | 客户关联 | 查询客户的所有订单 |
| idx_order_created_at | 普通索引 | `created_at` | 时间排序 | 时间范围查询 |
| idx_order_shop_status_date | 复合索引 | `(shop_id, status, created_at)` | 店铺状态时间查询 | 店铺内状态时间筛选 |
| idx_order_customer_status | 复合索引 | `(customer_id, status, created_at)` | 客户状态时间查询 | 客户订单状态查询 |

### 3.6 订单明细表 (cf_order_item)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询订单项 |
| idx_order_item_order_id | 普通索引 | `order_id` | 订单关联 | 查询订单的所有订单项 |
| idx_order_item_product_id | 普通索引 | `product_id` | 商品关联 | 查询商品的所有订单项 |
| idx_order_item_order_product | 复合索引 | `(order_id, product_id)` | 订单商品组合 | 订单内商品查询 |

### 3.7 广告表 (cf_advertisement)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询广告 |
| idx_ad_tenant_id | 普通索引 | `tenant_id` | 租户关联 | 查询租户的所有广告 |
| idx_ad_shop_id | 普通索引 | `shop_id` | 店铺关联 | 查询店铺的所有广告 |
| idx_ad_product_id | 普通索引 | `product_id` | 商品关联 | 查询商品的所有广告 |
| idx_ad_campaign_id | 普通索引 | `campaign_id` | 活动关联 | 查询活动的所有广告 |
| idx_ad_status | 普通索引 | `status` | 状态筛选 | 按状态查询广告 |
| idx_ad_platform | 普通索引 | `platform` | 平台筛选 | 按平台查询广告 |
| idx_ad_date_range | 复合索引 | `(start_date, end_date, status)` | 日期范围状态查询 | 广告时间范围查询 |
| idx_ad_shop_campaign | 复合索引 | `(shop_id, campaign_id, status)` | 店铺活动状态查询 | 店铺内活动广告查询 |

### 3.8 广告指标表 (cf_ad_metrics)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询指标 |
| idx_ad_metrics_ad_id | 普通索引 | `ad_id` | 广告关联 | 查询广告的所有指标 |
| idx_ad_metrics_date | 普通索引 | `date` | 日期筛选 | 按日期查询指标 |
| idx_ad_metrics_ad_date | 唯一索引 | `(ad_id, date)` | 广告日期唯一 | 广告每日指标查询 |
| idx_ad_metrics_date_range | 复合索引 | `(ad_id, date, spend)` | 日期范围花费查询 | 广告花费趋势查询 |

### 3.9 证书表 (cf_certificate)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询证书 |
| idx_cert_tenant_id | 普通索引 | `tenant_id` | 租户关联 | 查询租户的所有证书 |
| idx_cert_shop_id | 普通索引 | `shop_id` | 店铺关联 | 查询店铺的所有证书 |
| idx_cert_type | 普通索引 | `certificate_type` | 类型筛选 | 按类型查询证书 |
| idx_cert_status | 普通索引 | `status` | 状态筛选 | 按状态查询证书 |
| idx_cert_expiry_date | 普通索引 | `expiry_date` | 过期日期 | 过期证书查询 |
| idx_cert_shop_type_status | 复合索引 | `(shop_id, certificate_type, status)` | 店铺类型状态查询 | 店铺内证书类型查询 |

### 3.10 合规规则表 (cf_compliance_rule)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询规则 |
| idx_rule_platform | 普通索引 | `platform` | 平台筛选 | 按平台查询规则 |
| idx_rule_product_category | 普通索引 | `product_category` | 分类筛选 | 按分类查询规则 |
| idx_rule_status | 普通索引 | `status` | 状态筛选 | 按状态查询规则 |
| idx_rule_platform_category | 复合索引 | `(platform, product_category, status)` | 平台分类状态查询 | 平台分类规则查询 |

### 3.11 审计日志表 (cf_audit_log)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询日志 |
| idx_audit_tenant_id | 普通索引 | `tenant_id` | 租户关联 | 查询租户的所有日志 |
| idx_audit_user_id | 普通索引 | `user_id` | 用户关联 | 查询用户的所有操作 |
| idx_audit_action | 普通索引 | `action` | 操作类型 | 按操作类型查询 |
| idx_audit_resource_type | 普通索引 | `resource_type` | 资源类型 | 按资源类型查询 |
| idx_audit_created_at | 普通索引 | `created_at` | 操作时间 | 时间范围查询 |
| idx_audit_user_action_date | 复合索引 | `(user_id, action, created_at)` | 用户操作时间查询 | 用户操作历史查询 |
| idx_audit_tenant_resource_date | 复合索引 | `(tenant_id, resource_type, created_at)` | 租户资源时间查询 | 租户资源操作查询 |

## 4. 安全与测试表索引

### 4.1 安全测试表 (cf_security_test)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询测试 |
| idx_security_test_created_at | 普通索引 | `created_at` | 创建时间 | 时间范围查询 |
| idx_security_test_target_url | 普通索引 | `target_url` | 目标URL | 按URL查询测试 |

### 4.2 安全扫描表 (cf_security_scan)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询扫描 |
| idx_security_scan_created_at | 普通索引 | `created_at` | 创建时间 | 时间范围查询 |
| idx_security_scan_project_root | 普通索引 | `project_root` | 项目路径 | 按项目查询扫描 |

### 4.3 P0检查表 (cf_p0_check)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询检查 |
| idx_p0_check_created_at | 普通索引 | `created_at` | 创建时间 | 时间范围查询 |
| idx_p0_check_check_time | 普通索引 | `check_time` | 检查时间 | 检查时间查询 |

### 4.4 回归测试表 (cf_regression_test)

| 索引名称 | 索引类型 | 索引列 | 描述 | 适用场景 |
|----------|----------|--------|------|----------|
| PRIMARY | 主键索引 | `id` | 主键查询 | 通过ID查询测试 |
| idx_regression_test_created_at | 普通索引 | `created_at` | 创建时间 | 时间范围查询 |
| idx_regression_test_test_suite | 普通索引 | `test_suite` | 测试套件 | 按套件查询测试 |
| idx_regression_test_environment | 普通索引 | `environment` | 环境 | 按环境查询测试 |
| idx_regression_test_success | 普通索引 | `success` | 测试结果 | 按结果查询测试 |

## 5. 索引使用建议

### 5.1 查询优化建议

1. **使用覆盖索引**：尽量设计能够覆盖查询的索引，减少回表操作
2. **避免索引失效**：
   - 避免在索引列上使用函数
   - 避免使用 `NOT IN`、`!=` 等操作符
   - 避免使用 `LIKE '%keyword'` 前缀模糊查询
   - 保持索引列的顺序与查询条件一致
3. **合理使用复合索引**：遵循最左前缀原则
4. **定期分析索引使用情况**：使用 `EXPLAIN` 分析查询执行计划

### 5.2 维护建议

1. **定期重建索引**：对于频繁更新的表，定期重建索引以保持性能
2. **监控索引大小**：避免索引过大影响存储和性能
3. **删除无用索引**：定期清理未使用的索引
4. **优化索引统计信息**：定期更新索引统计信息

## 6. 性能优化案例

### 6.1 案例1：商品列表查询

**原始查询**：
```sql
SELECT * FROM cf_product WHERE shop_id = '123' AND category = 'electronics' AND status = 'ACTIVE' ORDER BY created_at DESC LIMIT 20;
```

**优化方案**：
创建复合索引 `idx_product_shop_category_status_created`：
```sql
CREATE INDEX idx_product_shop_category_status_created 
ON cf_product (shop_id, category, status, created_at);
```

**预期效果**：
- 避免全表扫描
- 直接通过索引获取排序结果
- 减少查询时间 80% 以上

### 6.2 案例2：订单状态统计

**原始查询**：
```sql
SELECT status, COUNT(*) FROM cf_order WHERE shop_id = '456' AND created_at BETWEEN '2026-01-01' AND '2026-01-31' GROUP BY status;
```

**优化方案**：
创建复合索引 `idx_order_shop_created_status`：
```sql
CREATE INDEX idx_order_shop_created_status 
ON cf_order (shop_id, created_at, status);
```

**预期效果**：
- 利用索引进行范围扫描
- 直接通过索引完成分组统计
- 减少查询时间 70% 以上

### 6.3 案例3：广告效果分析

**原始查询**：
```sql
SELECT SUM(impressions), SUM(clicks), SUM(spend), SUM(revenue) 
FROM cf_ad_metrics 
WHERE ad_id = '789' AND date BETWEEN '2026-01-01' AND '2026-01-31';
```

**优化方案**：
创建复合索引 `idx_ad_metrics_ad_date`（已存在）：
```sql
CREATE INDEX idx_ad_metrics_ad_date 
ON cf_ad_metrics (ad_id, date);
```

**预期效果**：
- 利用索引进行范围扫描
- 直接通过索引完成聚合计算
- 减少查询时间 90% 以上

## 7. 索引管理工具

### 7.1 索引监控

1. **查询索引使用情况**：
   ```sql
   SHOW INDEX FROM table_name;
   ```

2. **分析查询执行计划**：
   ```sql
   EXPLAIN SELECT * FROM table_name WHERE condition;
   ```

3. **监控索引大小**：
   ```sql
   SELECT table_name, index_name, ROUND(SUM(index_length) / 1024 / 1024, 2) AS index_size_mb 
   FROM information_schema.statistics 
   WHERE table_schema = 'your_database' 
   GROUP BY table_name, index_name 
   ORDER BY index_size_mb DESC;
   ```

### 7.2 索引维护

1. **重建索引**：
   ```sql
   ALTER TABLE table_name ENGINE=InnoDB;
   ```

2. **优化表**：
   ```sql
   OPTIMIZE TABLE table_name;
   ```

3. **删除无用索引**：
   ```sql
   DROP INDEX index_name ON table_name;
   ```

## 8. 总结

本索引设计文档为 Crawlful Hub 系统提供了全面的索引策略，包括：

1. **核心表索引设计**：为所有核心业务表设计了合理的索引
2. **复合索引优化**：针对常见查询场景设计了复合索引
3. **性能优化建议**：提供了具体的查询优化和索引维护建议
4. **实际案例分析**：通过具体案例展示了索引优化的效果

合理的索引设计是提高数据库性能的关键因素，通过本设计文档的实施，可以显著提升系统的查询性能和响应速度，为用户提供更好的体验。
