# 4. 平台存储系统深度解析

## ⚠️ 重要声明

**本项目仅供学习和研究目的使用**，使用者应严格遵守以下原则：

1. **不得用于任何商业用途**
2. 使用时应遵守目标平台的使用条款和robots.txt规则
3. 不得进行大规模爬取或对平台造成运营干扰
4. 应合理控制请求频率，避免给目标平台带来不必要的负担
5. 不得用于任何非法或不当的用途

详细许可条款请参阅项目根目录下的 [LICENSE](../LICENSE) 文件。

---

## 1. 存储系统整体架构

### 1.1 存储层架构概览

```mermaid
graph TB
    subgraph "应用层"
        A[VideoProcessor视频处理器]
        B[CommentProcessor评论处理器]
        C[CreatorHandler创作者处理器]
    end
    
    subgraph "存储抽象层"
        D[AbstractStore抽象基类]
        E[BiliStoreFactory工厂类]
    end
    
    subgraph "存储实现层"
        F[BiliCsvStoreImplement CSV存储]
        G[BiliDbStoreImplement 数据库存储]
        H[BiliJsonStoreImplement JSON存储]
    end
    
    subgraph "数据持久化层"
        I[CSV文件系统 data_bilibili]
        J[MySQL数据库 bilibili_video表]
        K[JSON文件系统 data_bilibili_json]
    end
    
    subgraph "数据访问层"
        L[bilibili_store_sql SQL操作]
        M[AsyncMysqlDB_数据库连接]
    end
    
    A --> E
    B --> E
    C --> E
    
    E --> D
    D --> F
    D --> G
    D --> H
    
    F --> I
    G --> L
    H --> K
    
    L --> M
    M --> J
    
    style E fill:#e3f2fd
    style D fill:#fff3e0
    style F fill:#e8f5e8
    style G fill:#e8f5e8
    style H fill:#e8f5e8
```

### 1.2 存储策略选择机制

```mermaid
graph LR
    A[配置文件 config.SAVE_DATA_OPTION] --> B{存储类型选择}
    B -->|"csv"| C[BiliCsvStoreImplement]
    B -->|"db"| D[BiliDbStoreImplement]
    B -->|"json"| E[BiliJsonStoreImplement]
    
    subgraph "CSV存储特性"
        F[简单易用]
        G[无需数据库]
        H[不支持去重]
        I[适合小规模数据]
    end
    
    subgraph "数据库存储特性"
        J[强一致性]
        K[支持去重]
        L[高性能查询]
        M[推荐用于生产]
    end
    
    subgraph "JSON存储特性"
        N[结构化存储]
        O[易于分析]
        P[文件大小适中]
        Q[支持嵌套数据]
    end
    
    C --> F
    C --> G
    C --> H
    C --> I
    
    D --> J
    D --> K
    D --> L
    D --> M
    
    E --> N
    E --> O
    E --> P
    E --> Q
    
    style B fill:#fff3e0
    style C fill:#e8f5e8
    style D fill:#e3f2fd
    style E fill:#f3e5f5
```

## 2. 抽象设计模式分析

### 2.1 AbstractStore抽象基类

```mermaid
classDiagram
    class AbstractStore {
        <<abstract>>
        +store_content(content_item: Dict)* 
        +store_comment(comment_item: Dict)*
        +store_creator(creator: Dict)*
    }
    
    class BiliCsvStoreImplement {
        +csv_store_path: str
        +file_count: int
        +make_save_file_name(store_type: str): str
        +save_data_to_csv(save_item: Dict, store_type: str)
        +store_content(content_item: Dict)
        +store_comment(comment_item: Dict)
        +store_creator(creator: Dict)
    }
    
    class BiliDbStoreImplement {
        +store_content(content_item: Dict)
        +store_comment(comment_item: Dict)
        +store_creator(creator: Dict)
    }
    
    class BiliJsonStoreImplement {
        +json_store_path: str
        +lock: asyncio.Lock
        +file_count: int
        +make_save_file_name(store_type: str): str
        +save_data_to_json(save_item: Dict, store_type: str)
        +store_content(content_item: Dict)
        +store_comment(comment_item: Dict)
        +store_creator(creator: Dict)
    }
    
    AbstractStore <|-- BiliCsvStoreImplement
    AbstractStore <|-- BiliDbStoreImplement
    AbstractStore <|-- BiliJsonStoreImplement
```

### 2.2 工厂模式实现

```mermaid
graph TB
    subgraph "工厂模式结构"
        A[BiliStoreFactory工厂类]
        B[STORES配置字典]
        C[create_store静态方法]
    end
    
    subgraph "产品类层次"
        D[AbstractStore抽象产品]
        E[BiliCsvStoreImplement具体产品1]
        F[BiliDbStoreImplement具体产品2]
        G[BiliJsonStoreImplement具体产品3]
    end
    
    subgraph "配置驱动"
        H[config.SAVE_DATA_OPTION]
        I["csv" 配置值]
        J["db" 配置值]
        K["json" 配置值]
    end
    
    A --> B
    A --> C
    B --> E
    B --> F
    B --> G
    
    C --> D
    D --> E
    D --> F
    D --> G
    
    H --> I
    H --> J
    H --> K
    
    I --> E
    J --> F
    K --> G
    
    style A fill:#e3f2fd
    style C fill:#fff3e0
    style D fill:#e8f5e8
```

## 3. CSV存储实现深度分析

### 3.1 CSV存储架构

```mermaid
graph TB
    subgraph "CSV存储组件"
        A[BiliCsvStoreImplement]
        B[csv_store_path存储路径]
        C[file_count文件计数]
        D[make_save_file_name文件命名]
        E[save_data_to_csv数据写入]
    end
    
    subgraph "文件管理策略"
        F[目录结构 data/bilibili/]
        G[文件命名规则 序号_类型_日期.csv]
        H[数据类型分离 contents/comments/creators]
        I[文件头处理 自动添加CSV头]
    end
    
    subgraph "异步文件操作"
        J[aiofiles异步文件库]
        K[utf-8-sig编码处理]
        L[csv.writer写入器]
        M[pathlib路径处理]
    end
    
    A --> B
    A --> C
    A --> D
    A --> E
    
    D --> F
    D --> G
    E --> H
    E --> I
    
    E --> J
    E --> K
    E --> L
    B --> M
    
    style A fill:#e3f2fd
    style E fill:#fff3e0
    style J fill:#e8f5e8
```

### 3.2 CSV文件命名与组织

```mermaid
sequenceDiagram
    participant App as 应用程序
    participant CSV as BiliCsvStoreImplement
    participant FileSystem as 文件系统
    participant Counter as 计数器工具
    
    App->>CSV: store_content(content_item)
    CSV->>Counter: calculate_number_of_files()
    Counter->>FileSystem: 扫描data/bilibili/目录
    FileSystem-->>Counter: 返回现有文件列表
    Counter-->>CSV: 返回下一个文件序号
    
    CSV->>CSV: make_save_file_name("contents")
    Note over CSV: 生成文件名格式<br/>1_search_contents_20240124.csv
    
    CSV->>FileSystem: 检查文件是否存在
    alt 文件不存在
        CSV->>FileSystem: 创建新文件并写入CSV头
    else 文件已存在
        CSV->>FileSystem: 追加数据到现有文件
    end
    
    CSV->>FileSystem: 写入内容数据
    FileSystem-->>CSV: 确认写入成功
    CSV-->>App: 存储完成
```

### 3.3 CSV数据格式示例

```mermaid
graph TB
    subgraph "CSV文件结构示例"
        A[文件头 Headers]
        B[视频内容数据行]
        C[评论数据行]
        D[创作者数据行]
    end
    
    subgraph "内容字段结构"
        E[video_id 视频ID]
        F[title 视频标题]
        G[desc 视频描述]
        H[create_time 发布时间]
        I[user_id 用户ID]
        J[nickname 用户昵称]
        K[liked_count 点赞数]
        L[video_play_count 播放量]
        M[source_keyword 搜索关键词]
    end
    
    A --> E
    A --> F
    A --> G
    A --> H
    A --> I
    A --> J
    A --> K
    A --> L
    A --> M
    
    B --> E
    C --> I
    D --> I
    
    style A fill:#fff3e0
    style B fill:#e8f5e8
    style C fill:#f3e5f5
    style D fill:#e3f2fd
```

## 4. 数据库存储实现深度分析

### 4.1 数据库存储架构

```mermaid
graph TB
    subgraph "数据库存储层次"
        A[BiliDbStoreImplement存储实现]
        B[bilibili_store_sql SQL操作层]
        C[AsyncMysqlDB数据库连接层]
        D[MySQL数据库]
    end
    
    subgraph "数据表结构"
        E[bilibili_video视频表]
        F[bilibili_video_comment评论表]
        G[bilibili_up_info UP主表]
    end
    
    subgraph "SQL操作接口"
        H[query_content_by_content_id查询]
        I[add_new_content新增]
        J[update_content_by_content_id更新]
        K[query_comment_by_comment_id查询]
        L[add_new_comment新增]
        M[update_comment_by_comment_id更新]
    end
    
    subgraph "数据去重机制"
        N[主键去重 video_id]
        O[存在检查 先查询后决定]
        P[更新策略 更新last_modify_ts]
        Q[时间戳管理 add_ts/last_modify_ts]
    end
    
    A --> B
    B --> C
    C --> D
    
    D --> E
    D --> F
    D --> G
    
    B --> H
    B --> I
    B --> J
    B --> K
    B --> L
    B --> M
    
    A --> N
    A --> O
    A --> P
    A --> Q
    
    style A fill:#e3f2fd
    style B fill:#fff3e0
    style N fill:#e8f5e8
```

### 4.2 数据库去重流程

```mermaid
sequenceDiagram
    participant App as 应用层
    participant Store as BiliDbStoreImplement
    participant SQL as bilibili_store_sql
    participant DB as MySQL数据库
    
    App->>Store: store_content(content_item)
    Store->>SQL: query_content_by_content_id(video_id)
    SQL->>DB: SELECT * FROM bilibili_video WHERE video_id=?
    DB-->>SQL: 返回查询结果
    SQL-->>Store: 返回现有记录或空字典
    
    alt 记录不存在
        Store->>Store: 添加add_ts时间戳
        Store->>SQL: add_new_content(content_item)
        SQL->>DB: INSERT INTO bilibili_video VALUES(...)
        DB-->>SQL: 返回插入行ID
        SQL-->>Store: 返回last_row_id
    else 记录已存在
        Store->>SQL: update_content_by_content_id(video_id, content_item)
        SQL->>DB: UPDATE bilibili_video SET ... WHERE video_id=?
        DB-->>SQL: 返回影响行数
        SQL-->>Store: 返回effect_row
    end
    
    Store-->>App: 存储操作完成
```

### 4.3 数据库表结构设计

```mermaid
erDiagram
    bilibili_video {
        int id PK "自增ID"
        varchar user_id "用户ID"
        varchar nickname "用户昵称"
        varchar avatar "用户头像地址"
        bigint add_ts "记录添加时间戳"
        bigint last_modify_ts "记录最后修改时间戳"
        varchar video_id UK "视频ID (aid)"
        varchar bvid "视频ID (bvid)"
        varchar video_type "视频类型"
        varchar title "视频标题"
        longtext desc "视频描述"
        bigint create_time "视频发布时间戳"
        varchar liked_count "视频点赞数"
        varchar video_play_count "视频播放数量"
        varchar video_danmaku "视频弹幕数量"
        varchar video_comment "视频评论数量" 
        varchar video_url "视频详情URL"
        varchar video_cover_url "视频封面图URL"
        varchar source_keyword "搜索来源关键字"
    }
    
    bilibili_video_comment {
        int id PK "自增ID"
        varchar user_id "用户ID"
        varchar nickname "用户昵称"
        varchar avatar "用户头像地址"
        bigint add_ts "记录添加时间戳"
        bigint last_modify_ts "记录最后修改时间戳"
        varchar comment_id UK "评论ID"
        varchar video_id FK "视频ID"
        longtext content "评论内容"
        bigint create_time "评论时间戳"
        varchar sub_comment_count "评论回复数"
        varchar parent_comment_id "父评论ID"
        varchar like_count "点赞数"
    }
    
    bilibili_up_info {
        int id PK "自增ID"
        varchar user_id UK "用户ID"
        varchar nickname "用户昵称"  
        varchar avatar "用户头像地址"
        bigint follower_count "粉丝数"
        bigint following_count "关注数"
        bigint content_count "作品数"
        longtext description "用户描述"
        bigint add_ts "记录添加时间戳"
        bigint last_modify_ts "记录最后修改时间戳"
    }
    
    bilibili_video ||--o{ bilibili_video_comment : "video_id"
    bilibili_up_info ||--o{ bilibili_video : "user_id"
```

## 5. JSON存储实现深度分析

### 5.1 JSON存储架构

```mermaid
graph TB
    subgraph "JSON存储组件"
        A[BiliJsonStoreImplement]
        B[json_store_path存储路径]
        C[asyncio.Lock并发锁]
        D[make_save_file_name文件命名]
        E[save_data_to_json数据写入]
    end
    
    subgraph "并发安全机制"
        F[异步锁保护]
        G[原子读写操作]
        H[数据完整性保证]
        I[避免文件损坏]
    end
    
    subgraph "JSON文件管理"
        J[文件存在检查]
        K[现有数据读取]
        L[数据追加策略]
        M[JSON格式化输出]
    end
    
    subgraph "数据结构优化"
        N[嵌套数据支持]
        O[Unicode字符处理]
        P[数组形式存储]
        Q[可读性优化]
    end
    
    A --> B
    A --> C
    A --> D
    A --> E
    
    E --> F
    E --> G
    C --> H
    C --> I
    
    E --> J
    E --> K
    E --> L
    E --> M
    
    M --> N
    M --> O
    M --> P
    M --> Q
    
    style A fill:#e3f2fd
    style C fill:#fff3e0
    style E fill:#e8f5e8
```

### 5.2 JSON并发写入流程

```mermaid
sequenceDiagram
    participant App1 as 应用线程1
    participant App2 as 应用线程2
    participant JSON as BiliJsonStoreImplement
    participant Lock as asyncio.Lock
    participant File as 文件系统
    
    App1->>JSON: store_content(content_item1)
    App2->>JSON: store_content(content_item2)
    
    JSON->>Lock: acquire() 线程1请求锁
    Lock-->>JSON: 获取锁成功
    
    JSON->>Lock: acquire() 线程2请求锁
    Note over Lock: 线程2等待锁释放
    
    JSON->>File: 读取现有JSON文件
    File-->>JSON: 返回现有数据数组
    JSON->>JSON: 将新数据追加到数组
    JSON->>File: 写入完整数据到文件
    File-->>JSON: 写入完成
    
    JSON->>Lock: release() 释放锁
    Lock-->>JSON: 线程2获取锁
    
    JSON->>File: 读取现有JSON文件
    File-->>JSON: 返回包含item1的数据
    JSON->>JSON: 将item2追加到数组
    JSON->>File: 写入包含item1和item2的数据
    File-->>JSON: 写入完成
    
    JSON->>Lock: release() 释放锁
    
    JSON-->>App1: 存储完成
    JSON-->>App2: 存储完成
```

### 5.3 JSON数据结构示例

```mermaid
graph TB
    subgraph "JSON文件结构"
        A[根数组 Array]
        B[视频对象1 Object]
        C[视频对象2 Object]
        D[视频对象N Object]
    end
    
    subgraph "视频对象结构"
        E[video_id_字符串]
        F[title_字符串]
        G[desc_长文本]
        H[create_time_时间戳]
        I[user_info_嵌套对象]
        J[stats_统计对象]
        K[urls_URL对象]
        L[metadata_元数据对象]
    end
    
    subgraph "嵌套对象示例"
        M[user_info_user_id]
        N[user_info_nickname]
        O[stats_liked_count]
        P[stats_play_count]
        Q[urls_video_url]
        R[urls_cover_url]
    end
    
    A --> B
    A --> C
    A --> D
    
    B --> E
    B --> F
    B --> G
    B --> H
    B --> I
    B --> J
    B --> K
    B --> L
    
    I --> M
    I --> N
    J --> O
    J --> P
    K --> Q
    K --> R
    
    style A fill:#e3f2fd
    style B fill:#e8f5e8
    style I fill:#fff3e0
    style J fill:#fff3e0
```


## 7. 存储系统扩展性设计

### 7.1 多平台存储架构

```mermaid
graph TB
    subgraph "存储抽象层"
        A[AbstractStore基类]
    end
    
    subgraph "平台存储实现"
        B[BilibiliStore_B站存储]
        C[DouyinStore_抖音存储]
        D[XhsStore_小红书存储]
        E[WeiboStore_微博存储]
        F[KuaishouStore_快手存储]
    end
    
    subgraph "存储类型支持"
        G[CSV文件存储]
        H[JSON文件存储]
        I[MySQL数据库存储]
        J[MongoDB文档存储]
        K[Redis缓存存储]
    end
    
    subgraph "工厂模式管理"
        L[StoreFactory工厂]
        M[配置驱动创建]
        N[运行时类型选择]
        O[插件化扩展支持]
    end
    
    A --> B
    A --> C
    A --> D
    A --> E
    A --> F
    
    B --> G
    B --> H
    B --> I
    C --> G
    C --> H
    C --> I
    
    L --> M
    L --> N
    L --> O
    
    M --> B
    M --> C
    M --> D
    
    style A fill:#e3f2fd
    style L fill:#fff3e0
    style G fill:#e8f5e8
    style H fill:#e8f5e8
    style I fill:#e8f5e8
```

### 7.2 新存储类型集成

```mermaid
sequenceDiagram
    participant Dev as 开发者
    participant Abstract as AbstractStore
    participant New as NewStoreImplement
    participant Factory as StoreFactory
    participant Config as 配置系统
    
    Dev->>Abstract: 继承AbstractStore
    Dev->>New: 实现store_content()
    Dev->>New: 实现store_comment()
    Dev->>New: 实现store_creator()
    
    Dev->>Factory: 注册新存储类型
    Note over Factory: STORES["new_type"] = NewStoreImplement
    
    Dev->>Config: 添加配置选项
    Note over Config: SAVE_DATA_OPTION = "new_type"
    
    Factory->>New: create_store()
    New-->>Factory: 返回存储实例
    
    Note over Dev,Config: 无需修改现有代码<br/>即可支持新存储类型
```

## 8. 最佳实践与总结

建议都选择DB存储，因为DB存储支持去重，并且支持复杂查询

### 8.2 系统设计优势

1. **抽象设计**: 统一的存储接口，支持多种存储后端
2. **工厂模式**: 配置驱动的存储类型选择，易于扩展
3. **数据去重**: 数据库存储支持自动去重，避免重复数据
4. **异步操作**: 全异步IO操作，提升系统性能
5. **并发安全**: 完善的锁机制和事务处理
6. **错误处理**: 完备的异常处理和恢复机制

### 10.3 学习要点总结

```mermaid
mindmap
  root((存储系统学习要点))
    设计模式
      抽象基类设计
      工厂模式应用
      策略模式实现
      组合模式使用
    存储技术
      CSV文件操作
      JSON数据处理
      MySQL数据库
      异步IO编程
    性能优化
      索引设计
      批量操作
      并发控制
      缓存策略
    数据管理
      去重机制
      数据一致性
      事务处理
      异常恢复
```

---

**再次提醒：本项目仅供学习和研究目的使用，请严格遵守相关法律法规和平台使用条款，不得用于任何商业用途或违法行为。通过学习本存储系统，您可以深入理解现代爬虫系统的数据持久化设计模式和最佳实践。**