ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

实战案例表结构设计:从业务分析到数据库建表全攻略

2026/8/31 17:04:28 拓冰建站 浏览量
实战案例表结构设计:从业务分析到数据库建表全攻略 开发项目或搭建业务系统时一提到“表结构设计”很多同学第一反应是建几张表、写几个字段就行。但真正落地到 150 个实战案例这种规模时你会发现表结构不只是存储数据它决定了后续的检索效率、统计维度、权限控制、报表展示甚至团队协作方式。本文围绕“实战案例表结构和业务说明”这一主题从实际业务场景出发完整拆解一套可用于案例管理系统的数据库设计方案并给出每张表的建表语句、字段含义和业务规则说明。内容覆盖关系型数据库设计、Datagrip 同步表结构、JimuReport 报表数据源配置等常见操作适合后端开发、数据开发、项目管理人员参考。1. 背景为什么需要一套规范的实战案例表结构1.1 实战案例管理的真实痛点在很多团队里实战案例的存放方式五花八门Excel 表格、本地 Markdown 文件、语雀文档、GitLab Wiki、甚至聊天记录里的压缩包。当案例数量到了上百个时问题会集中爆发想知道某个技术栈下有哪些案例需要人工翻文档。案例的维护人、审核状态、发布时间没有统一记录。不同人写的字段格式不一样统计报表根本无法自动化。案例文件和案例描述分离时间久了文件丢失或对不上号。新成员加入团队后缺少一套可检索、可筛选、可追溯的案例库。解决这些问题的核心不是先写代码而是先把表结构设计清楚。表结构是所有上层功能的地基地基不稳后面做接口、做页面、做报表都会返工。1.2 本文的解决方案本文将以一个“实战案例管理系统”为例设计一套覆盖案例分类、案例主体、标签、附件、学习记录、扩展属性等核心业务的数据库表结构。案例数量按 150 条数据规模设计但表结构同样适用于 1000 条、10000 条甚至更大规模。学习完本文你将掌握一套完整的实战案例表结构设计思路。每张核心表的 DDL 建表语句和字段业务含义。案例状态流转、权限边界、数据归档等业务规则。使用 Datagrip 同步表结构的操作步骤。使用 JimuReport 这类报表工具直接读取案例表生成统计看板的思路。数据库设计中的常见坑和最佳实践。2. 环境准备与版本说明2.1 数据库选型本文示例以 MySQL 8.0 为主因为 8.0 在窗口函数、JSON 类型、字符集支持方面比 5.7 更友好。如果你使用的是 MySQL 5.7大部分 DDL 仍然适用但需要注意utf8mb4 字符集在 5.7 中同样支持推荐优先使用。如果用到窗口函数或公用表表达式CTE5.7 不支持需要改写 SQL。JSON 类型在 5.7 中已支持但部分函数有所差异。如果你的团队使用的是 PostgreSQL、Oracle 或 SQL Server设计思路可以复用但数据类型和部分语法需要调整。2.2 工具准备本文涉及以下工具MySQL 数据库服务建议使用 8.0 及以上版本。数据库客户端工具DataGrip、Navicat、MySQL Workbench 均可。本文以 DataGrip 为例讲解表结构同步演示。可选JimuReport积木报表用于报表展示通过 Spring Boot Starter 集成。可选Postman 或 Apifox用于后续接口联调。版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路不把某个版本写死。2.3 项目结构如果后续要基于这套表结构开发后端服务建议按模块拆分case-management/ ├── sql/ │ └── init.sql ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/example/case/ │ │ │ ├── controller/ │ │ │ ├── service/ │ │ │ ├── mapper/ │ │ │ ├── entity/ │ │ │ └── common/ │ │ └── resources/ │ │ ├── application.yml │ │ └── mapper/ │ └── test/ └── pom.xml本文重点在 sql 目录下的表结构设计和业务说明后续可以在此基础上继续开发接口层和应用层。3. 表结构设计的核心原则3.1 业务驱动设计设计表结构之前先梳理业务对象。以一个 150 个实战案例的案例管理系统为例业务对象大致如下案例分类案例属于哪个技术方向或业务方向。案例主信息标题、摘要、案例类型、难度等级、维护人、发布时间等。案例内容正文详情通常是大字段。案例标签用于灵活打标例如“Spring Boot”“高并发”“数据分析”。案例附件配套的代码压缩包、数据文件、PDF 文档。案例学习记录用户学习案例的进度、评论、收藏情况。案例审核状态用于记录状态变更流程。案例扩展属性不同案例类型可能需要不同的额外字段。先画出业务对象关系再开始建表。不要一上来就写 CREATE TABLE那样容易出现字段缺失、表关系混乱的问题。3.2 三大范式与反范式数据库设计通常提到三大范式第一范式字段原子性不可再分。第二范式消除部分依赖。第三范式消除传递依赖。但在实际业务中不需要死守范式。例如“案例类型”通常用 t_case_type 表维护但如果在列表页频繁查询类型名称可以冗余一个 type_name 字段到主表避免每次 JOIN。这种做法属于反范式设计目的是提升查询性能。本文采用“范式为主、局部冗余为辅”的策略。3.3 主键设计推荐使用自增主键主键字段统一命名为 id类型为 BIGINT UNSIGNED。原因如下BIGINT 范围大支持未来数据增长。UNSIGNED 可以充分利用正数空间。自增主键在 InnoDB 引擎下插入性能较好。在分布式场景下可以改用雪花ID或 UUID但本文以单库为主。3.4 公共字段每张业务表建议包含以下公共字段id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT 主键ID create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间 update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间 deleted TINYINT NOT NULL DEFAULT 0 COMMENT 逻辑删除0-未删除1-已删除其中 deleted 字段是为了避免物理删除导致数据丢失。实际业务中案例的标题、内容、附件可能涉及追溯和审计所以使用逻辑删除是更安全的方式。3.5 状态字段状态字段建议使用 TINYINT 类型并且把枚举值写清楚。比如status TINYINT NOT NULL DEFAULT 0 COMMENT 状态0-草稿1-待审核2-已发布3-已下架4-已归档不要用无注释的数字也不要在代码里散落魔法值。最好在 Java 枚举、数据库注释、接口文档三处保持一致。4. 完整实战150 个实战案例表结构设计4.1 业务表清单表名统一使用小写字母和下划线分隔业务前缀使用 case_关联表使用 rel 后缀。表名业务说明case_category案例分类表case_info实战案例主表case_content案例内容表case_tag标签表case_tag_rel案例标签关联表case_attachment案例附件表case_study_record案例学习记录表case_ext_info案例扩展信息表下面逐个说明建表语句和业务含义。4.2 案例分类表 case_category案例分类是树形结构例如“后端开发 Spring Boot”“前端开发 Vue3”“人工智能 深度学习实战项目案例”。这里使用 parent_id 实现父子层级。CREATE TABLE case_category ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 分类ID, parent_id BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 父分类ID0表示顶级分类, category_name VARCHAR(64) NOT NULL COMMENT 分类名称, category_code VARCHAR(64) NOT NULL COMMENT 分类编码唯一, sort_no INT NOT NULL DEFAULT 0 COMMENT 排序号越小越靠前, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, deleted TINYINT NOT NULL DEFAULT 0 COMMENT 逻辑删除0-未删除1-已删除, PRIMARY KEY (id), UNIQUE KEY uk_category_code (category_code), KEY idx_parent_id (parent_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci COMMENT实战案例分类表;字段说明parent_id 为 0 时表示顶级分类。查询某个分类下所有子分类时可以用递归查询或在代码中逐层查询。category_code 应该唯一例如 backend_springboot方便代码中做映射。sort_no 用于控制前端展示顺序不推荐用分类ID排序因为新增分类会影响展示位置。业务示例数据idparent_idcategory_namecategory_code10后端开发backend21Spring Bootbackend_springboot31数据库实战backend_database40人工智能ai54深度学习实战项目案例ai_deeplearning4.3 实战案例主表 case_info这是整个系统的核心表一条记录代表一个实战案例。为了让列表页查询高效把常用检索字段直接冗余在主表。CREATE TABLE case_info ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 案例ID, case_no VARCHAR(32) NOT NULL COMMENT 案例编号业务唯一, title VARCHAR(200) NOT NULL COMMENT 案例标题, summary VARCHAR(500) DEFAULT NULL COMMENT 案例摘要, category_id BIGINT UNSIGNED NOT NULL COMMENT 所属分类ID, category_name VARCHAR(64) DEFAULT NULL COMMENT 分类名称冗余便于列表展示, case_type TINYINT NOT NULL DEFAULT 1 COMMENT 案例类型1-后端2-前端3-AI/算法4-数据分析5-运维6-其他, difficulty TINYINT NOT NULL DEFAULT 1 COMMENT 难度等级1-入门2-进阶3-高级, source VARCHAR(64) DEFAULT NULL COMMENT 案例来源内部项目、开源项目、培训课程等, owner_id BIGINT UNSIGNED NOT NULL COMMENT 维护人ID, owner_name VARCHAR(64) DEFAULT NULL COMMENT 维护人姓名冗余, status TINYINT NOT NULL DEFAULT 0 COMMENT 状态0-草稿1-待审核2-已发布3-已下架4-已归档, view_count INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 浏览量, like_count INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 点赞数, collect_count INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 收藏数, publish_time DATETIME DEFAULT NULL COMMENT 发布时间, last_audit_time DATETIME DEFAULT NULL COMMENT 最近审核时间, last_auditor VARCHAR(64) DEFAULT NULL COMMENT 最近审核人, audit_remark VARCHAR(500) DEFAULT NULL COMMENT 审核备注, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, deleted TINYINT NOT NULL DEFAULT 0 COMMENT 逻辑删除0-未删除1-已删除, PRIMARY KEY (id), UNIQUE KEY uk_case_no (case_no), KEY idx_category_id (category_id), KEY idx_status (status), KEY idx_case_type (case_type), KEY idx_owner_id (owner_id), KEY idx_publish_time (publish_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci COMMENT实战案例主表;字段设计说明case_no 是业务编号例如 CASE-202501-001方便线下沟通时引用同时可以作为唯一标识。case_type 和 category_id 看起来有点重复但两者用途不同。case_type 是固定的技术大方向category_id 是树形分类。比如“深度学习实战项目案例”属于分类而 case_type 固定为 AI/算法。difficulty 字段便于按难度筛选适合不同水平的学习者。owner_id 和 owner_name 冗余是因为列表页需要频繁显示维护人JOIN 用户表会增加查询开销。如果用户名称变更需要同步更新这里。status 的变更需要走业务流程后面会单独说明状态流转。view_count、like_count、collect_count 属于统计字段。追求更高性能时可以拆到独立统计表或用缓存异步更新但 150 条案例的规模下直接放主表即可。4.4 案例内容表 case_content案例主表只存摘要和列表字段正文内容可能非常大因此单独拆一张表。CREATE TABLE case_content ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键ID, case_id BIGINT UNSIGNED NOT NULL COMMENT 案例ID, content_md MEDIUMTEXT COMMENT Markdown格式正文内容, content_html MEDIUMTEXT COMMENT 渲染后的HTML内容, version INT NOT NULL DEFAULT 1 COMMENT 内容版本号, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, deleted TINYINT NOT NULL DEFAULT 0 COMMENT 逻辑删除0-未删除1-已删除, PRIMARY KEY (id), UNIQUE KEY uk_case_id (case_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci COMMENT实战案例内容表;字段说明content_md 保存 Markdown 原文方便编辑。content_html 保存渲染后的 HTML方便前端直接展示避免每次请求都做 Markdown 解析。如果团队不需要双格式存储可以只保留 content_md前端实时解析。但从性能角度考虑存量数据大时建议双写。这里有一个需要注意的地方MEDIUMTEXT 最大存储 16MB 左右对于一般实战文档足够。如果案例中包含大量截图或较长视频解析文本可以使用 LONGTEXT但也要评估是否应该把二进制文件放到对象存储中。4.5 标签表 case_tag标签用于灵活打标例如“高并发”“分布式事务”“数据可视化”“前端项目实战案例”。CREATE TABLE case_tag ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 标签ID, tag_name VARCHAR(32) NOT NULL COMMENT 标签名称, tag_code VARCHAR(32) DEFAULT NULL COMMENT 标签编码, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, deleted TINYINT NOT NULL DEFAULT 0 COMMENT 逻辑删除0-未删除1-已删除, PRIMARY KEY (id), UNIQUE KEY uk_tag_name (tag_name) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci COMMENT案例标签表;4.6 案例标签关联表 case_tag_rel案例和标签是多对多关系因此需要关联表。CREATE TABLE case_tag_rel ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键ID, case_id BIGINT UNSIGNED NOT NULL COMMENT 案例ID, tag_id BIGINT UNSIGNED NOT NULL COMMENT 标签ID, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), UNIQUE KEY uk_case_tag (case_id, tag_id), KEY idx_tag_id (tag_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci COMMENT案例标签关联表;为什么不直接在 case_info 表中用一个 tag_ids 字符串保存例如 “1,2,3”。虽然简单但无法做高效的标签筛选也无法统计某个标签下有多少案例。用关联表可以支持按标签筛选案例。统计热门标签。按案例删除标签。标签改名后只需更新 case_tag 表。4.7 案例附件表 case_attachment案例可能附带代码包、SQL 脚本、数据集文件、PPT 等附件。CREATE TABLE case_attachment ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 附件ID, case_id BIGINT UNSIGNED NOT NULL COMMENT 案例ID, file_name VARCHAR(255) NOT NULL COMMENT 原始文件名, file_path VARCHAR(500) NOT NULL COMMENT 存储路径或对象存储KEY, file_size BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 文件大小单位字节, file_type VARCHAR(32) DEFAULT NULL COMMENT 文件类型ZIP、SQL、PDF、MD等, down_count INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 下载次数, uploader_id BIGINT UNSIGNED NOT NULL COMMENT 上传人ID, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, deleted TINYINT NOT NULL DEFAULT 0 COMMENT 逻辑删除0-未删除1-已删除, PRIMARY KEY (id), KEY idx_case_id (case_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci COMMENT案例附件表;设计要点file_path 存储的是相对路径或对象存储 Key不建议存完整公网 URL因为域名或存储桶可能调整。如果附件是敏感数据需要增加权限控制在查询时校验当前用户是否允许下载。文件本身建议放到 OSS / MinIO / 分布式文件系统中数据库只存元数据。4.8 案例学习记录表 case_study_record如果案例库面向团队内部培训或学员学习可以记录用户的学习行为。CREATE TABLE case_study_record ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键ID, case_id BIGINT UNSIGNED NOT NULL COMMENT 案例ID, user_id BIGINT UNSIGNED NOT NULL COMMENT 用户ID, progress TINYINT NOT NULL DEFAULT 0 COMMENT 学习进度0-100, is_favorite TINYINT NOT NULL DEFAULT 0 COMMENT 是否收藏0-否1-是, is_like TINYINT NOT NULL DEFAULT 0 COMMENT 是否点赞0-否1-是, last_view_time DATETIME DEFAULT NULL COMMENT 最后查看时间, study_duration INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 学习时长单位秒, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 首次学习时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 最近学习时间, PRIMARY KEY (id), UNIQUE KEY uk_case_user (case_id, user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci COMMENT案例学习记录表;字段说明使用唯一约束 uk_case_user保证同一个用户对同一个案例只有一条学习记录。is_favorite、is_like 放在学习记录中而不是直接更新 case_info 表是为了减少对主表的并发更新。case_info 中的 like_count、collect_count 可以定期从学习记录表聚合更新也可以在点赞/收藏时同步更新。4.9 案例扩展信息表 case_ext_info不同案例类型需要不同的扩展字段例如“深度学习实战项目案例”需要记录数据集大小、模型精度、训练耗时“前端项目实战案例”需要记录技术栈版本、兼容性说明。这里使用键值对结构实现扩展属性。CREATE TABLE case_ext_info ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键ID, case_id BIGINT UNSIGNED NOT NULL COMMENT 案例ID, attr_key VARCHAR(64) NOT NULL COMMENT 扩展属性Key, attr_value VARCHAR(1000) DEFAULT NULL COMMENT 扩展属性Value, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_case_attr (case_id, attr_key) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci COMMENT案例扩展信息表;使用扩展表的好处是灵活不需要频繁修改表结构。但代价是查询扩展属性时需要多次查询或行转列。在 150 条案例规模下性能不是瓶颈可以接受。如果未来扩展字段非常固定建议直接加列到 case_info 表或 case_content 表因为键值对查询不太友好。两种方式需要根据业务稳定性来选择。5. 业务说明与状态流转5.1 案例状态机case_info 表中的 status 字段定义如下状态0-草稿维护人创建案例后保存尚未提交审核。1-待审核维护人提交审核此时不允许编辑正文只能撤回。2-已发布审核通过并发布前台可见。3-已下架发布后因内容问题或维护人主动下架前台不可见。4-已归档案例长期不更新或已完成历史使命进入归档状态。状态流转方向0-草稿 - 1-待审核 - 2-已发布 - 3-已下架 - 2-已发布 - 4-已归档 1-待审核 - 0-草稿撤回每条状态变更建议同步记录到操作日志表中。不要只改 status 字段否则后续无法追溯“谁在什么时间把案例从已发布改成了已下架原因是什么”。5.2 权限边界针对不同角色数据权限不同普通用户只能查看已发布的案例可以收藏、点赞、记录学习进度。案例维护人可以创建案例草稿编辑自己名下案例提交审核下架自己的案例。案例审核人可以查看待审核列表通过或驳回案例。系统管理员可以修改所有案例状态管理分类、标签、用户权限。在后续开发接口时建议使用 Spring Security 或 Shiro 做权限控制。数据库层面查询语句要强制带上 status 条件避免未发布数据被泄露。5.3 分类与标签的业务边界分类是树形结构适合做“目录式导航”例如一级分类“后端开发”二级分类“Spring Boot”。标签是扁平的适合做“交叉筛选”例如“高并发”“MySQL”“Redis”。一个案例只能属于一个分类但可以有多个标签。设计时要注意分类不要设计得太深一般两层到三层即可。标签数量控制在 3 到 10 个之间太少不利于检索太多容易产生噪音。删除分类前需要检查该分类下是否还有案例如果有需要先迁移或禁用分类。6. 使用 DataGrip 同步表结构6.1 为什么需要同步表结构在团队协作中开发环境、测试环境、生产环境的数据库结构需要保持一致。如果每位开发都在自己本地手动执行 SQL容易出现字段缺失、索引不一致等问题。使用 DataGrip 可以比较两个数据库的表结构差异并生成同步脚本。6.2 DataGrip 同步表结构操作步骤第一步在 DataGrip 左侧 Database 面板中连接源数据库和目标数据库。第二步选择要同步的数据库或表右键点击选择“Database Tools” - “Compare and Migrate”。第三步在差异列表中勾选需要同步的表、视图、索引等对象。第四步点击“Apply”或“Execute”生成同步脚本DataGrip 会先展示差异 SQL确认无误后再执行。第五步执行完成后在目标数据库刷新表结构检查是否同步成功。6.3 同步表结构注意事项不要在业务高峰期直接在生产库执行结构变更。尤其是大表添加字段或索引时可能造成锁表。建议先在测试环境执行一遍确认 SQL 无误后再同步生产。如果目标表已有数据注意字段新增时是否有默认值避免空值影响业务。同步前手动备份目标库至少导出相关表的数据和结构。7. 报表与可视化接入 JimuReport 生成统计看板7.1 JimuReport 是什么JimuReport 是一款开源的数据可视化报表工具通过 Spring Boot Starter 集成后可以直接连接数据库表通过可视化拖拽方式生成列表报表、汇总报表、图表看板。对于“150 个实战案例”这种规模的数据统计场景使用 JimuReport 可以快速实现以下效果按案例类型统计数量。按难度等级统计数量。按分类展示案例排行。展示各维护人的案例贡献量。展示案例发布趋势。7.2 接入思路以 jimureport-spring-boot-starter 为例核心步骤如下。在 pom.xml 中引入依赖dependency groupIdorg.jeecgframework.jimureport/groupId artifactIdjimureport-spring-boot-starter/artifactId version请根据项目实际版本填写/version /dependency在 application.yml 中配置数据源spring: datasource: url: jdbc:mysql://localhost:3306/case_db?useUnicodetruecharacterEncodingutf8mb4useSSLfalse username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver启动项目后访问 JimuReport 的设计器页面新建数据集配置数据源后编写查询 SQL。例如统计案例类型分布SELECT CASE WHEN case_type 1 THEN 后端 WHEN case_type 2 THEN 前端 WHEN case_type 3 THEN AI/算法 WHEN case_type 4 THEN 数据分析 WHEN case_type 5 THEN 运维 ELSE 其他 END AS type_name, COUNT(*) AS case_count FROM case_info WHERE deleted 0 AND status 2 GROUP BY case_type ORDER BY case_count DESC;在 JimuReport 中用轮播图、饼图或柱状图展示这段 SQL 的查询结果即可。7.3 注意事项JimuReport 的版本升级较快不同版本的配置类和权限校验方式可能有差异。本文不把具体版本写死集成时以官方文档为准。特别提醒JimuReport 如果暴露在公网需要配置访问权限避免未授权用户查看报表数据或执行 SQL。生产环境推荐内网部署或使用 Spring Security 进行统一认证。8. 常见问题与排查思路8.1 表结构设计阶段常见问题问题现象常见原因解决思路查询案例列表非常慢表内缺乏索引或 WHERE 条件使用了函数为 category_id、status、case_type 等字段加索引避免在索引列上使用函数案例内容丢失格式只存 HTML 或只存 Markdown使用双字段存储Markdown 用于编辑HTML 用于展示标签筛选不准使用字符串存储标签ID增加多对多关联表用 JOIN 或子查询实现筛选案例分类调整后历史数据错误分类删除时未处理子分类和案例删除前校验是否有引用支持禁用分类而不是物理删除附件找不到文件数据库只存文件名不存相对路径增加 file_path 字段并确保对象存储路径可追踪8.2 DataGrip 同步表结构常见问题问题现象常见原因解决思路同步时提示外键冲突表之间外键依赖顺序不对先删除外键再同步结构最后重新添加外键同步后中文乱码数据库字符集或连接字符集不一致统一使用 utf8mb4检查连接参数 characterEncoding同步脚本执行失败目标库存在同名对象在 Compare 面板取消勾选已存在对象或先备份再执行本地表结构和线上不一致有人直接改线下库以 SQL 脚本文件为基线所有修改通过脚本提交8.3 报表和统计常见问题问题现象常见原因解决思路报表数据不更新缓存机制导致查看报表缓存配置或执行清缓存操作报表 SQL 查不到数据表名前缀或库名不对检查数据源配置SQL 中使用完整的库名.表名统计结果包含已删除数据未过滤 deleted 字段所有查询统一定义公共条件deleted 0大文本字段导致查询慢content_html 字段过大报表查询避免关联 case_content只统计主表字段9. 索引设计与 SQL 优化建议9.1 索引设计原则优先给 WHERE、ORDER BY、GROUP BY 中频繁使用的字段建立索引。联合索引字段顺序遵循“最左前缀”原则。例如经常按 category_id status 查询可以建立联合索引ALTER TABLE case_info ADD INDEX idx_category_status (category_id, status);不要在一个表上建立过多索引因为写入和更新都会带来额外开销。案例规模 150 条时几个核心索引即可。状态字段区分度不高单独建索引的意义有限通常与分类、类型等字段组合使用。9.2 高频查询示例按分类筛选并统计案例数SELECT category_id, COUNT(*) AS total FROM case_info WHERE deleted 0 AND status 2 GROUP BY category_id;按标签筛选案例SELECT ci.id, ci.title FROM case_info ci JOIN case_tag_rel ctr ON ci.id ctr.case_id JOIN case_tag ct ON ctr.tag_id ct.id WHERE ci.deleted 0 AND ci.status 2 AND ct.tag_code springboot ORDER BY ci.publish_time DESC;查询最近发布的 10 条深度学习实战项目案例SELECT id, title, summary, publish_time FROM case_info WHERE deleted 0 AND status 2 AND case_type 3 ORDER BY publish_time DESC LIMIT 10;9.3 防止慢查询案例表在初期数据量不大但随着时间增长content 表、study_record 表的数据量会快速扩大。建议开启 MySQL 慢查询日志定期分析慢 SQL。SET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 1;这行命令表示开启慢查询日志并记录执行时间超过 1 秒的 SQL。生产环境建议结合监控系统做持久化分析。10. 最佳实践与工程建议10.1 命名与注释规范表名、字段名统一小写以下划线分隔。所有表和字段必须写 COMMENT方便后续维护。主键统一命名为 id业务编号单独用 case_no 等字段表示。布尔字段使用 TINYINT用 0 和 1 表示不要使用 BIT 或 CHAR(1)。金额、浮点数要用 DECIMAL不要用 FLOAT 或 DOUBLE。10.2 数据安全与备份设计表时要有逻辑删除字段但查询时一定要在 SQL 中显式过滤 deleted 0。生产环境执行 DDL 前先备份相关表。备份命令示例mysqldump -u root -p case_db case_info case_info_backup.sql不要在生产环境直接使用 root 账号执行 DDL使用最小权限账号。附件等物理文件需要通过存储服务控制访问权限数据库记录不能直接暴露。10.3 写入操作注意事项批量插入案例时注意控制单批数量避免长事务占用行锁。更新浏览量这类高频字段时可以考虑异步累计或者分批合并更新避免频繁 UPDATE case_info 表。状态变更要走审核流程不建议直接修改 status 字段。可以使用独立状态变更表记录审计日志例如 case_audit_log。10.4 可扩展性如果后续需要搜索功能可以将 case_info、case_content 同步到 Elasticsearch。如果案例数量到达几万条可以考虑将 content_html 独立存储到对象存储减少数据库压力。如果团队需要多人协作可以引入工作流引擎管理审核流程但 150 个案例规模下用状态机即可不需要过度设计。11. 总结与下一步实践方向这篇文章围绕“实战案例表结构和业务说明”完整演示了一套案例管理系统的数据库设计。从业务对象梳理开始依次完成了分类表、案例主表、内容表、标签表、附件表、学习记录表、扩展信息表的建表语句和字段说明并补充了状态流转、权限边界、Datagrip 同步表结构、JimuReport 报表对接、索引优化和常见问题等内容。设计表结构时最重要的不是一上来写代码而是先想清楚业务规则一个案例有哪些核心属性案例之间是什么关系谁在维护案例案例状态如何变化报表需要统计哪些维度。表结构一旦确定后续的接口开发、前端页面、报表看板都会顺畅很多。接下来你可以继续做以下实践基于这套表结构编写 Spring Boot 后端接口实现案例的增删改查和审核流程。在数据库客户端中导入全部建表 SQL插入 150 条测试数据验证常用查询的性能。集成 JimuReport按本文的 SQL 示例配置案例分类统计报表。如果团队内部有用户体系结合 Spring Security 做权限控制明确不同角色的数据访问边界。如果在实际落地过程中遇到字段设计不合理或数据量快速增长的情况不用怕先调整表结构再通过同步工具保证各环境一致。数据库设计本身就是不断演进的过程。