Vibe Coding一人即团队系列30: AI辅助数据库脚本设计与字符集问题修复

纲要

  • 数据库脚本生成: 基于 PRD 与前端项目结构,利用 AI 辅助设计并生成 DDL 脚本
  • 核心表结构: 用户表 (users)、账户表 (accounts)、分类表 (categories)、交易记录表 (transactions)、预算表 (budgets)
  • 脚本执行与验证: 在数据库管理工具中执行脚本,完成表结构与初始数据的部署
  • 字符集乱码问题: 排查与修复机制,采用 utf8mb4 字符集与 utf8mb4_unicode_ci 排序规则,确保支持 emoji 表情存储
  • 数据库管理角色演进: 从专职 DBA 到后端开发承担,再到 AI 辅助下的单人团队 (Vibe Coding 团队) 实践

数据库脚本生成:从需求到 DDL

在项目开发中,数据库表结构设计是决定后续业务扩展性与维护成本的关键环节。在已经完成数据库环境安装的前提下,通过 AI 编码助手,可以根据现有的产品 PRD 文档以及前端项目代码,自动生成一份专业级的数据库脚本。这一过程不仅能够显著缩短设计周期,还能在一定程度上保证字段命名、数据类型以及表间关联关系的规范性。

执行脚本生成时,需要将上下文信息(如前端项目路径、PRD 描述)提供给 AI 工具。AI 会解析这些内容,识别出核心业务实体,并转化为对应的 SQL DDL 语句。相较于传统的人工建表方式,AI 生成的脚本通常包含了完整的字段注释、主键、外键约束以及索引建议,这对于后续的团队协作或单人维护都具有极高的参考价值。

核心表结构说明

基于本次项目的财务管理系统 (FinanceManager),AI 生成的数据库脚本主要包含以下核心表:
#mermaid-svg-FRLf26GRZR8yUS98{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FRLf26GRZR8yUS98 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FRLf26GRZR8yUS98 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FRLf26GRZR8yUS98 .error-icon{fill:#552222;}#mermaid-svg-FRLf26GRZR8yUS98 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FRLf26GRZR8yUS98 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FRLf26GRZR8yUS98 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FRLf26GRZR8yUS98 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FRLf26GRZR8yUS98 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FRLf26GRZR8yUS98 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FRLf26GRZR8yUS98 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FRLf26GRZR8yUS98 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FRLf26GRZR8yUS98 .marker.cross{stroke:#333333;}#mermaid-svg-FRLf26GRZR8yUS98 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FRLf26GRZR8yUS98 p{margin:0;}#mermaid-svg-FRLf26GRZR8yUS98 .entityBox{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-FRLf26GRZR8yUS98 .relationshipLabelBox{fill:hsl(80, 100%, 96.2745098039%);opacity:0.7;background-color:hsl(80, 100%, 96.2745098039%);}#mermaid-svg-FRLf26GRZR8yUS98 .relationshipLabelBox rect{opacity:0.5;}#mermaid-svg-FRLf26GRZR8yUS98 .labelBkg{background-color:rgba(248.6666666666, 255, 235.9999999999, 0.5);}#mermaid-svg-FRLf26GRZR8yUS98 .edgeLabel .label{fill:#9370DB;font-size:14px;}#mermaid-svg-FRLf26GRZR8yUS98 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FRLf26GRZR8yUS98 .edge-pattern-dashed{stroke-dasharray:8,8;}#mermaid-svg-FRLf26GRZR8yUS98 .node rect,#mermaid-svg-FRLf26GRZR8yUS98 .node circle,#mermaid-svg-FRLf26GRZR8yUS98 .node ellipse,#mermaid-svg-FRLf26GRZR8yUS98 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FRLf26GRZR8yUS98 .relationshipLine{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-FRLf26GRZR8yUS98 .marker{fill:none!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-FRLf26GRZR8yUS98 .edgeLabel{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FRLf26GRZR8yUS98 .edgeLabel .label rect{fill:rgba(232,232,232, 0.8);}#mermaid-svg-FRLf26GRZR8yUS98 .edgeLabel .label text{fill:#333;}#mermaid-svg-FRLf26GRZR8yUS98 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} has
creates
makes
involved
belongs_to
sets
targets
users
int
id
PK
varchar
username
varchar
email
varchar
password_hash
datetime
created_at
datetime
updated_at
accounts
int
id
PK
int
user_id
FK
varchar
account_name
varchar
account_type
decimal
balance
varchar
currency
datetime
created_at
categories
int
id
PK
int
user_id
FK
varchar
name
varchar
icon
varchar
color
varchar
type
EXPENSE or INCOME
transactions
int
id
PK
int
user_id
FK
int
account_id
FK
int
category_id
FK
decimal
amount
varchar
description
datetime
transaction_date
varchar
transaction_type
budgets
int
id
PK
int
user_id
FK
int
category_id
FK
decimal
amount
varchar
period
MONTHLY or YEARLY
datetime
start_date
datetime
end_date

在生成的脚本中,AI 已根据业务常规逻辑自动添加了必要的字段注释。如果发现某些表(例如与第三方支付集成相关的表)在当前版本中不需要,可以在后续沟通中要求 AI 移除或调整,这体现了 AI 辅助开发的高可迭代性。

说明: 根据业务语义,上述 ER 图中 accountstransactions 的关系为 "involved"(涉及),表示每笔交易记录会关联对应的账户,用于追溯资金流向。

表字段设计速览

以关键表为例,说明 AI 自动生成的数据类型与约束策略:

  • 用户表 (users) : 作为系统的核心基础表,包含 id (INT PRIMARY KEY AUTO_INCREMENT)、username (VARCHAR(50) UNIQUE NOT NULL)、email (VARCHAR(100) UNIQUE NOT NULL)、password_hash (VARCHAR(255) NOT NULL) 以及 created_atupdated_at (DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)。AI 默认启用了审计追踪字段,这对后期问题排查至关重要。

  • 交易记录表 (transactions) : 该表通过 user_idaccount_idcategory_id 建立了与用户、账户和分类的关联关系。金额字段 amount 使用 DECIMAL(10, 2) 类型,以保障财务数据的精确度。AI 设计时自动添加了 transaction_date 用于记录实际发生时间,区别于 created_at 的系统记录时间。

  • 预算表 (budgets) : 通过与 category_id 关联,实现了按分类进行预算控制的功能。period 字段使用了 ENUM 类型约束,限定了 MONTHLYYEARLY 两种周期,减少了业务逻辑层的数据校验负担。

数据库脚本执行与初始化

生成 DDL 脚本后,下一步是在数据库实例中执行该脚本。

这一过程可以直接在 SQL 执行窗口中运行,也可以通过在命令行中通过 source 命令导入。

执行成功后,数据库 FinanceManager 将包含完整的表结构。

sql 复制代码
-- AI 生成的脚本开头示例
CREATE DATABASE IF NOT EXISTS `FinanceManager`
    CHARACTER SET = 'utf8mb4'
    COLLATE = 'utf8mb4_unicode_ci';

USE `FinanceManager`;

-- 用户表
CREATE TABLE `users` (
    `id` INT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
    `username` VARCHAR(50) NOT NULL COMMENT '用户名',
    `email` VARCHAR(100) NOT NULL COMMENT '邮箱',
    `password_hash` VARCHAR(255) NOT NULL COMMENT '加密密码',
    `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`),
    UNIQUE INDEX `idx_username` (`username`),
    UNIQUE INDEX `idx_email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户基本信息表';

-- 交易记录表 (关键关联表示例)
CREATE TABLE `transactions` (
    `id` INT NOT NULL AUTO_INCREMENT COMMENT '交易ID',
    `user_id` INT NOT NULL COMMENT '用户ID',
    `account_id` INT NOT NULL COMMENT '账户ID',
    `category_id` INT NOT NULL COMMENT '分类ID',
    `amount` DECIMAL(10,2) NOT NULL COMMENT '交易金额',
    `description` VARCHAR(255) DEFAULT NULL COMMENT '交易描述',
    `transaction_date` DATETIME NOT NULL COMMENT '交易日期',
    `transaction_type` ENUM('EXPENSE', 'INCOME') NOT NULL COMMENT '交易类型',
    `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`),
    INDEX `idx_user_id` (`user_id`),
    INDEX `idx_account_id` (`account_id`),
    INDEX `idx_category_id` (`category_id`),
    CONSTRAINT `fk_transactions_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_transactions_account` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_transactions_category` FOREIGN KEY (`category_id`) REFERENCES `categories`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='交易流水记录表';

执行成功后,AI 还自动植入了部分测试数据,包括基础的支出/收入分类、演示账户及若干条交易流水。这一特性使得开发环境可以快速具备可演示的状态,缩短了从零到一的准备周期。

字符集乱码问题排查与修复

在实际操作中,由于数据库连接或脚本文件本身的字符集设置不一致,可能会导致表结构注释或记录内容显示为乱码。这是一个在数据库初始化过程中极为常见的场景。

问题分析

乱码现象通常由以下因素引起:

  • 脚本文件保存编码与数据库 character_set_client 不一致
  • 创建数据库时未显式指定 CHARACTER SETCOLLATE
  • 表或字段级别的字符集覆盖了数据库默认配置

在本次实践中,通过调整数据库字符集为 utf8mb4,问题得到彻底解决。utf8mb4UTF-8 的超集,兼容标准的 UTF-8 且支持四字节的 Unicode 字符(如 emoji)。

修复方案

  1. 检查当前字符集配置

    sql 复制代码
    SHOW VARIABLES LIKE 'character_set_%';
    SHOW VARIABLES LIKE 'collation_%';
  2. 修改数据库默认字符集

    sql 复制代码
    ALTER DATABASE FinanceManager
        CHARACTER SET = utf8mb4
        COLLATE = utf8mb4_unicode_ci;
  3. 修改表字符集(若已创建)

    sql 复制代码
    ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    -- 其余表按需执行相同操作

验证步骤

  • 重新建立数据库连接(刷新连接池或重启客户端)
  • 查询 INFORMATION_SCHEMA 确认字段字符集
  • 执行 SELECT 查询原乱码记录,观察是否正常显示

通过以上操作,注释中的中文以及测试数据中的特殊符号均可正确渲染,确保了数据在不同客户端环境下的兼容性。

API 速览

本实践涉及的核心 API 操作主要围绕数据库连接与元数据查询展开。以下示例基于 Python3PyMySQL 库,展示如何通过编程方式验证字符集配置。

python 复制代码
import pymysql

# 数据库连接配置
connection = pymysql.connect(
    host='localhost',
    user='your_username',
    password='your_password',
    database='FinanceManager',
    charset='utf8mb4',  # 关键: 确保连接使用 utf8mb4
    cursorclass=pymysql.cursors.DictCursor
)

def check_charset():
    with connection.cursor() as cursor:
        # 查询数据库字符集
        cursor.execute("SELECT @@character_set_database AS charset, @@collation_database AS collation;")
        result = cursor.fetchone()
        print(f"Database Charset: {result['charset']}, Collation: {result['collation']}")

        # 查询所有表的字符集
        cursor.execute("""
            SELECT TABLE_NAME, TABLE_COLLATION
            FROM INFORMATION_SCHEMA.TABLES
            WHERE TABLE_SCHEMA = 'FinanceManager';
        """)
        tables = cursor.fetchall()
        for table in tables:
            print(f"Table: {table['TABLE_NAME']}, Collation: {table['TABLE_COLLATION']}")

if __name__ == "__main__":
    check_charset()
    connection.close()

方法说明

  • PyMySQL.connect(): 建立数据库连接,charset='utf8mb4' 参数确保客户端与服务端使用一致的 Unicode 编码。
  • INFORMATION_SCHEMA.TABLES: 系统视图,用于获取数据库内所有表的元数据信息,便于批量审计和运维。

开发角色演进与 Vibe Coding 实践

在传统的软件工程流程中,数据库设计与优化通常由专职的 DBA (数据库管理员)负责。但随着敏捷开发和 DevOps 文化的普及,这一职责逐渐向后端开发人员转移。而在 Vibe Coding 一人团队模式下,AI 承担了"虚拟 DBA"和"初级后端开发"的辅助角色。
#mermaid-svg-8iZPaWb1YDj6ePZV{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8iZPaWb1YDj6ePZV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8iZPaWb1YDj6ePZV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8iZPaWb1YDj6ePZV .error-icon{fill:#552222;}#mermaid-svg-8iZPaWb1YDj6ePZV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8iZPaWb1YDj6ePZV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8iZPaWb1YDj6ePZV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8iZPaWb1YDj6ePZV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8iZPaWb1YDj6ePZV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8iZPaWb1YDj6ePZV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8iZPaWb1YDj6ePZV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8iZPaWb1YDj6ePZV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8iZPaWb1YDj6ePZV .marker.cross{stroke:#333333;}#mermaid-svg-8iZPaWb1YDj6ePZV svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8iZPaWb1YDj6ePZV p{margin:0;}#mermaid-svg-8iZPaWb1YDj6ePZV .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8iZPaWb1YDj6ePZV .cluster-label text{fill:#333;}#mermaid-svg-8iZPaWb1YDj6ePZV .cluster-label span{color:#333;}#mermaid-svg-8iZPaWb1YDj6ePZV .cluster-label span p{background-color:transparent;}#mermaid-svg-8iZPaWb1YDj6ePZV .label text,#mermaid-svg-8iZPaWb1YDj6ePZV span{fill:#333;color:#333;}#mermaid-svg-8iZPaWb1YDj6ePZV .node rect,#mermaid-svg-8iZPaWb1YDj6ePZV .node circle,#mermaid-svg-8iZPaWb1YDj6ePZV .node ellipse,#mermaid-svg-8iZPaWb1YDj6ePZV .node polygon,#mermaid-svg-8iZPaWb1YDj6ePZV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8iZPaWb1YDj6ePZV .rough-node .label text,#mermaid-svg-8iZPaWb1YDj6ePZV .node .label text,#mermaid-svg-8iZPaWb1YDj6ePZV .image-shape .label,#mermaid-svg-8iZPaWb1YDj6ePZV .icon-shape .label{text-anchor:middle;}#mermaid-svg-8iZPaWb1YDj6ePZV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8iZPaWb1YDj6ePZV .rough-node .label,#mermaid-svg-8iZPaWb1YDj6ePZV .node .label,#mermaid-svg-8iZPaWb1YDj6ePZV .image-shape .label,#mermaid-svg-8iZPaWb1YDj6ePZV .icon-shape .label{text-align:center;}#mermaid-svg-8iZPaWb1YDj6ePZV .node.clickable{cursor:pointer;}#mermaid-svg-8iZPaWb1YDj6ePZV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8iZPaWb1YDj6ePZV .arrowheadPath{fill:#333333;}#mermaid-svg-8iZPaWb1YDj6ePZV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8iZPaWb1YDj6ePZV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8iZPaWb1YDj6ePZV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8iZPaWb1YDj6ePZV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8iZPaWb1YDj6ePZV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8iZPaWb1YDj6ePZV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8iZPaWb1YDj6ePZV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8iZPaWb1YDj6ePZV .cluster text{fill:#333;}#mermaid-svg-8iZPaWb1YDj6ePZV .cluster span{color:#333;}#mermaid-svg-8iZPaWb1YDj6ePZV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8iZPaWb1YDj6ePZV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8iZPaWb1YDj6ePZV rect.text{fill:none;stroke-width:0;}#mermaid-svg-8iZPaWb1YDj6ePZV .icon-shape,#mermaid-svg-8iZPaWb1YDj6ePZV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8iZPaWb1YDj6ePZV .icon-shape p,#mermaid-svg-8iZPaWb1YDj6ePZV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8iZPaWb1YDj6ePZV .icon-shape .label rect,#mermaid-svg-8iZPaWb1YDj6ePZV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8iZPaWb1YDj6ePZV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8iZPaWb1YDj6ePZV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8iZPaWb1YDj6ePZV :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 符合预期
需要调整
产品需求 PRD
AI 辅助解析
生成数据库 DDL 脚本
人工审核与调整
执行脚本初始化数据库
AI 迭代修改
数据验证与测试
前端/后端联调
部署上线

在这一流程中,开发者扮演的是"架构师"与"审核者"的角色,负责把控业务方向并确保 AI 生成的方案符合项目长期规划。这种模式极大地降低了对单一技术栈专家的依赖,使得个人开发者或小型团队能够以较低的成本启动高质量的项目。

参考文档

官方文档

参考链接

总结

本次实践展示了在 Vibe Coding 一人团队模式下,利用 AI 工具从项目需求出发,自动化完成数据库脚本生成、表结构设计、数据初始化以及字符集编码问题修复的完整流程。

核心技术栈涵盖 MySQL 8.0utf8mb4 字符集配置、DDL 脚本的迭代生成策略以及 PyMySQL 的元数据验证方法。通过引入 AI 辅助开发,单人团队可以有效承担原本需要 DBA 与后端开发协同完成的工作,显著缩短项目启动周期并降低沟通成本。

相关推荐
可乐鸡翅yeah_15 分钟前
HTTPS 站点下 M3U8 混合内容问题深度排查,HLS 协议安全策略踩坑实录
数据库·网络协议·https·m3u8·m3u8在线
流浪00115 分钟前
大模型技术全景(一):AI、机器学习、深度学习,三者的关系到底是什么?一文搞懂
人工智能·深度学习·机器学习
雾削木16 分钟前
2026 编程领域热点知识速览:AI 辅助开发、设计模式实战与嵌入式高效迭代
人工智能·设计模式
show4331 小时前
2026小程序端AI配音技术实现:TTS多音色引擎集成与MP3生成优化
人工智能·小程序
CHEEVEN_QY3 小时前
B2B制造企业,AI搜索时代的信息架构怎么做
人工智能·制造·geo·结构化数据·b2b制造
月光船幽幽6 小时前
检测用户意图复杂性的关键方法
人工智能·python
疯狂打码的少年7 小时前
【数据库技术】关系模型基本概念(关系/属性/元组/键)
java·服务器·数据库·笔记
Henry-SAP7 小时前
AI突破重塑未来科技格局
人工智能·云原生·sap·erp
空堂与归8 小时前
图像识别总是准确率低?用卷积神经网络CNN实现高效分类
人工智能·深度学习·分类·cnn