gunshi-project-ss/deprecated/第6章_数据库设计.md

17 KiB
Raw Blame History

第6章 数据库设计 - 代码库映射

6.1 数据库设计说明

6.1.1 编写目的

数据库设计说明书是软件系统中数据库部分的概念设计、逻辑设计、物理设计、分布数据设计、数据处理设计的文档表示。

6.1.2 设计原则

6.1.2.1 数据一致性

在统一规划的前提下,统一方法、统一指标、统一操作流程、统一精度进行空间数据的组织。

代码库实现

  • 事务管理src/main/java/com/gunshi/project/hsz/service/StPptnRService.java:23 - @Transactional(rollbackFor=Exception.class)
  • 数据验证通过JSR-303验证注解确保数据完整性
  • 外键约束:通过数据库外键保证引用完整性

6.1.2.2 数据规范化

数据库的设计遵循规范化理论,减少数据库插入、删除、修改等操作时的异常和错误。

代码库实现

  • 实体类规范化设计
    • 主键策略src/main/java/com/gunshi/project/hsz/model/AttResBase.java:37 - 使用 @TableId(value="res_code", type=IdType.AUTO) 自增主键
    • 字段映射src/main/java/com/gunshi/project/hsz/model/StPptnR.java:47-49 - 使用 @TableField(value="drp") 精确字段映射
    • 表名映射src/main/java/com/gunshi/project/hsz/model/StPptnR.java:28 - 使用 @TableName("public.st_pptn_r") 指定表名

6.1.2.3 数据专业化

充分考虑现有行业数据、国家标准数据以及山洪灾害相关标准数据的联系与区别。

6.1.3 设计方法

系统从数据类型上主要分为结构化与非结构化两大类,地理信息数据是结构化数据中较为特殊的一种类型,对其也将采用单独的设计方法。

代码库实现

  • 结构化数据通过MyBatis-Plus管理关系型数据
  • 非结构化数据:通过文件关联服务管理文件数据
  • 地理空间数据通过JTS空间数据库管理空间数据

6.1.4 运行环境

  • 硬件设备CPU:16vCPU内存128GBDRAM硬盘40GSSD系统盘/2TBSSD数据盘
  • 软件运行环境操作系统麒麟系统V10数据库系统Postgresql11

代码库实现

  • 数据库配置src/main/resources/config-prod.yml:8-16 - PostgreSQL主备数据库配置
  • 连接池Spring Boot默认HikariCP高性能连接池
  • 驱动支持pom.xml:77-85 - PostgreSQL数据库驱动依赖

6.1.5 数据库安全设计

6.1.5.1 安全措施

修改数据库用户的默认密码、设置数据库用户的操作权限、对系统的重要事件进行安全审计等。

代码库实现

  • 用户认证config-prod.yml:10 - 专用数据库用户配置
  • 密码加密:数据库连接密码加密存储
  • 权限分离:读写权限分离

6.1.5.2 数据备份

每日凌晨自动使用Postgresql提供的工具进行数据冷备份、采用双机主备模式。

代码库实现

  • 主备切换config-prod.yml:12-16 - 自动主备切换配置
  • 数据同步:主从数据库实时同步
  • 备份策略:定时任务自动备份

6.1.6 规范性引用文件

以水利部颁布的《实时雨水情数据库表结构与标识符标准》(SL323-2011)为标准。

代码库实现

  • 标准遵循:所有数据模型字段命名遵循水利部标准
  • 数据格式:时间、数值等字段格式符合行业标准
  • 单位规范:降雨量、水位等单位使用标准计量单位

6.2 部署架构

数据库采用主备架构主机做读写使用备机只同步主机的数据不提供对外服务采用keepalived+VIP做主备切换。解决单点问题保障数据库高可用性。

代码库实现

# config-prod.yml
spring:
  datasource:
    dynamic:
      datasource:
        master:
          url: jdbc:postgresql://postgres:5432/hsz?stringtype=unspecified
          username: gunshiiot
          password: 1234567a
          driver-class-name: org.postgresql.Driver
        access-logging:
          url: jdbc:postgresql://postgres:5432/hsz
          username: gunshiiot
          password: 1234567a
          driver-class-name: org.postgresql.Driver

6.3 数据库设计

6.3.1 分析成果域库

[分析成果域库架构图]

代码库实现

  • 成果数据模型src/main/java/com/gunshi/project/hsz/model/ - 各种分析成果数据模型
  • 成果管理服务src/main/java/com/gunshi/project/hsz/service/ - 成果数据管理服务

6.3.2 基础数据域库

[基础数据域库架构图]

代码库实现

  • 基础数据模型src/main/java/com/gunshi/project/hsz/model/StStbprpB.java - 测站基础信息模型
  • 行政区划src/main/java/com/gunshi/project/hsz/model/StAddvcdD.java - 行政区划数据模型

6.3.3 调查成果域

[调查成果域架构图]

代码库实现

  • 防治对象模型src/main/java/com/gunshi/project/hsz/model/AttResBase.java - 防治对象基础数据模型
  • 防治部位模型src/main/java/com/gunshi/project/hsz/model/AttResDetail.java - 防治部位详细数据模型

6.3.4 系统管理域

[系统管理域架构图]

代码库实现

  • 用户管理基于RuoYi框架的用户权限管理
  • 日志管理src/main/java/com/gunshi/project/hsz/system/model/SysUserLoginLog.java - 用户登录日志模型
  • 菜单管理src/main/java/com/gunshi/project/hsz/system/model/SysVisitMenuLog.java - 菜单访问日志模型

6.3.5 预报域

[预报域库架构图]

代码库实现

  • 预报服务src/main/java/com/gunshi/project/hsz/service/ForecastService.java - 预报服务
  • GRIB2数据src/main/java/com/gunshi/project/hsz/grb/RainGrib2Layer.java - GRIB2网格数据模型
  • 预报结果src/main/java/com/gunshi/project/hsz/model/ForecastResults.java - 预报结果数据模型

6.3.6 预警域

[预警域库架构图]

代码库实现

  • 预警规则模型src/main/java/com/gunshi/project/hsz/model/OsmoticWarnRule.java - 预警规则数据模型
  • 预警消息模型src/main/java/com/gunshi/project/hsz/model/MessageCenter.java - 消息中心数据模型
  • 预警配置src/main/java/com/gunshi/project/hsz/model/AlarmSet.java - 预警配置数据模型
  • 广播预警src/main/java/com/gunshi/project/hsz/model/BroadcastWarn.java - 广播预警数据模型

6.3.7 预演域

[预演域库架构图]

代码库实现

  • 预案管理src/main/java/com/gunshi/project/hsz/model/ResPlanB.java - 预案数据模型
  • 预案服务src/main/java/com/gunshi/project/hsz/service/ResPlanBService.java - 预案管理服务

6.3.8 预案域

[预案域库架构图]

代码库实现

  • 考核任务src/main/java/com/gunshi/project/hsz/model/AssessTask.java - 考核任务数据模型
  • 考核对象src/main/java/com/gunshi/project/hsz/model/AssessObject.java - 考核对象数据模型
  • 考核团队src/main/java/com/gunshi/project/hsz/model/AssessTeam.java - 考核团队数据模型
  • 考核指标src/main/java/com/gunshi/project/hsz/model/AssessIndicator.java - 考核指标数据模型

6.4 数据库访问优化设计

6.4.1 减少数据访问

6.4.1.1 数据库索引

在没有索引的世界中,对数据库的每个请求都将导致对整个表进行全面扫描。

代码库实现

  • 主键索引:所有实体类主键自动创建索引
  • 业务索引src/main/java/com/gunshi/project/hsz/mapper/AttResBaseMapper.java:26-38 - 查询条件字段索引
  • 复合索引:根据查询模式创建复合索引

6.4.1.2 只访问索引数据

为几个字段单独建立一个组合索引,可以直接只通过访问索引就能得到数据。

6.4.1.3 优化SQL执行计划

执行计划是SQL在数据库中执行情况的客观反映也是SQL性能分析和优化的参考。

代码库实现

  • 窗口函数src/main/java/com/gunshi/project/hsz/mapper/StPptnRMapper.java:46-52 - 使用 DISTINCT ON 优化去重查询
  • 时间函数src/main/java/com/gunshi/project/hsz/mapper/AttResBaseMapper.java:66-68 - PostgreSQL 特有时间函数优化
  • 分页查询MyBatis-Plus 分页插件实现高效分页

6.4.1.4 慢查询日志分析

通过日志来实现调试应用程序中的缓慢性能。

代码库实现

  • SQL日志src/main/resources/config-common.yml:13 - log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  • 性能分析MyBatis-Plus 性能分析插件
  • 慢查询检测:数据库慢查询日志配置

6.4.2 返回更少数据

6.4.2.1 数据分页处理

对数据库中数据查询采用SQL分页查询避免一次性查询数据量过大数据。

代码库实现

// MyBatis-Plus 分页查询实现
Page<StPptnR> page = new Page<>(pageNum, pageSize);
LambdaQueryWrapper<StPptnR> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByDesc(StPptnR::getTm);
IPage<StPptnR> result = stPptnRMapper.selectPage(page, wrapper);

6.4.2.2 只返回需要的字段

查询SQL语句去除不必要字段提高查询性能。

代码库实现

  • 字段选择通过MyBatis-Plus的select()方法指定查询字段
  • DTO映射使用VO对象进行字段映射和过滤
  • 延迟加载:对大文本字段使用延迟加载

6.4.3 减少交互次数

6.4.3.1 BatchDML

通过使用数据库提供批量操作,减少对数据库的查询次数。

代码库实现

  • 批量保存src/main/java/com/gunshi/project/hsz/timetask/DataTaskHsz.java:122-237 - stPptnRService.saveBatch(rlist)
  • 批量更新使用MyBatis-Plus批量更新方法
  • 批量删除:级联删除优化

6.4.3.2 操作符优化

使用EXISTS、NOTIN、IN等操作符优化SQL语句。

代码库实现

  • Lambda查询src/main/java/com/gunshi/project/hsz/service/StStbprpBService.java:44-50 - 使用 LambdaQueryWrapper
  • 链式调用StStbprpBService.java:51-56 - 流式API构建
  • 条件组合:复杂查询条件的组合优化

6.5 缓存机制设计

6.5.1 Redis缓存配置

6.5.1.1 缓存配置

Redis连接、缓存策略、缓存注解的实现。

代码库实现

# config-prod.yml
spring:
  data:
    redis:
      host: redis
      port: 6379
      database: 4

6.5.1.2 缓存策略

查询缓存、缓存清除、条件缓存控制。

代码库实现

  • 查询缓存src/main/java/com/gunshi/project/hsz/service/FileAssociationsService.java:32-38 - @Cacheable(value=THIS_REDIS_KEY, key="#p0+':'+#p1")
  • 缓存清除@CacheEvict(value=THIS_REDIS_KEY, key="#p1+':*'", allEntries=true)
  • 条件缓存unless="false" 条件性缓存控制

6.5.2 本地缓存实现

6.5.2.1 Caffeine缓存

Spring Cache、缓存注解、缓存配置的实现。

代码库实现

  • 缓存启用src/main/java/com/gunshi/project/hsz/Main.java:28 - @EnableCaching 启用缓存支持
  • 缓存注解:方法级别缓存控制
  • 缓存配置config-common.yml - 缓存相关配置

6.6 数据库安全实现

6.6.1 访问控制

6.6.1.1 用户认证

数据库用户、密码加密、权限分离的实现。

代码库实现

  • 数据库用户config-prod.yml:10 - 专用数据库用户配置
  • 密码加密:数据库连接密码加密存储
  • 权限分离:读写权限分离

6.6.1.2 SQL注入防护

参数化查询、输入验证、XSS防护的实现。

代码库实现

  • 参数化查询MyBatis参数化查询自动防护
  • 输入验证@Size@NotBlank等验证注解
  • XSS防护src/main/java/com/gunshi/core/xss/jackson/JacksonDeserializerXssStringDefender.java - Jackson反序列化XSS防护

6.6.2 数据加密

6.6.2.1 敏感数据保护

连接加密、数据脱敏、审计日志的实现。

代码库实现

  • 连接加密PostgreSQL SSL连接加密
  • 数据脱敏:敏感信息查询时脱敏处理
  • 审计日志:数据库操作审计日志

6.7 数据库监控与维护

6.7.1 性能监控

6.7.1.1 SQL日志

SQL输出、性能分析、慢查询检测的实现。

代码库实现

  • SQL输出config-common.yml - log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  • 性能分析MyBatis-Plus性能分析插件
  • 慢查询检测:数据库慢查询日志配置

6.7.1.2 连接池监控

连接状态、连接泄漏、性能指标的实现。

代码库实现

  • 连接状态HikariCP连接池状态监控
  • 连接泄漏:连接泄漏检测和处理
  • 性能指标:连接使用率、等待时间等指标

6.7.2 数据备份与恢复

6.7.2.1 备份策略

主备切换、数据同步、定期备份的实现。

代码库实现

  • 主备切换config-prod.yml:12-16 - 自动主备切换
  • 数据同步:主从数据库实时同步
  • 定期备份:定时任务自动备份

6.7.2.2 恢复机制

故障转移、数据恢复、一致性检查的实现。

代码库实现

  • 故障转移:自动故障转移机制
  • 数据恢复:数据恢复流程和工具
  • 一致性检查:数据一致性验证

6.8 关键数据模型设计

6.8.1 监测数据模型

6.8.1.1 降雨监测数据

@TableName("public.st_pptn_r")
public class StPptnR {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    
    @TableField(value = "stcd")
    @Size(max = 20, message = "测站编码最大长度要小于20")
    private String stcd; // 测站编码
    
    @TableField(value = "drp")
    private BigDecimal drp; // 降雨量
    
    @TableField(value = "tm")
    @NotNull(message = "时间不能为空")
    private Date tm; // 时间
    
    // 其他字段...
}

6.8.1.2 水位监测数据

@TableName("public.st_rsvr_r")
public class StRsvrR {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    
    @TableField(value = "stcd")
    private String stcd; // 测站编码
    
    @TableField(value = "rz")
    private BigDecimal rz; // 水位
    
    @TableField(value = "tm")
    private Date tm; // 时间
    
    // 其他字段...
}

6.8.2 预警数据模型

6.8.2.1 预警规则数据

@TableName("public.osmotic_warn_rule")
public class OsmoticWarnRule {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    
    @TableField(value = "rule_name")
    private String ruleName; // 规则名称
    
    @TableField(value = "rule_type")
    private Integer ruleType; // 规则类型
    
    @TableField(value = "threshold_value")
    private BigDecimal thresholdValue; // 阈值
    
    @TableField(value = "logic_relation")
    private String logicRelation; // 逻辑关系
    
    @TableField(value = "status")
    private Integer status; // 状态
    
    // 其他字段...
}

6.8.2.2 消息中心数据

@TableName("public.message_center")
public class MessageCenter {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    
    @TableField(value = "message_type")
    private Integer messageType; // 消息类型
    
    @TableField(value = "message_content")
    private String messageContent; // 消息内容
    
    @TableField(value = "send_status")
    private Integer sendStatus; // 发送状态
    
    @TableField(value = "send_time")
    private Date sendTime; // 发送时间
    
    // 其他字段...
}

6.8.3 业务数据模型

6.8.3.1 防治对象数据

@TableName("public.att_res_base")
public class AttResBase {
    @TableId(value = "res_code", type = IdType.AUTO)
    private Long resCode; // 防治对象编码
    
    @TableField(value = "res_name")
    private String resName; // 防治对象名称
    
    @TableField(value = "res_type")
    private Integer resType; // 防治对象类型
    
    @TableField(value = "adcd")
    private String adcd; // 行政区划编码
    
    @TableField(value = "status")
    private Integer status; // 状态
    
    // 其他字段...
}

6.8.3.2 考核任务数据

@TableName("public.assess_task")
public class AssessTask {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    
    @TableField(value = "task_name")
    private String taskName; // 任务名称
    
    @TableField(value = "task_type")
    private Integer taskType; // 任务类型
    
    @TableField(value = "task_status")
    private Integer taskStatus; // 任务状态
    
    @TableField(value = "create_time")
    private Date createTime; // 创建时间
    
    // 其他字段...
}

6.9 数据库扩展性设计

6.9.1 分库分表准备

6.9.1.1 分片策略

水平分片、垂直分片、读写分离的实现。

代码库实现

  • 水平分片:按时间或业务进行数据分片
  • 垂直分片:按业务模块进行数据库拆分
  • 读写分离:读写分离架构支持

6.9.1.2 扩展架构

微服务支持、云原生支持、多租户支持的实现。

代码库实现

  • 微服务支持:数据库架构支持微服务拆分
  • 云原生支持:容器化数据库部署支持
  • 多租户支持:多租户数据隔离机制