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

498 lines
17 KiB
Markdown
Raw Normal View 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做主备切换。解决单点问题保障数据库高可用性。
**代码库实现**
```yaml
# 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分页查询避免一次性查询数据量过大数据。
**代码库实现**
```java
// 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连接、缓存策略、缓存注解的实现。
**代码库实现**
```yaml
# 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 降雨监测数据
```java
@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 水位监测数据
```java
@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 预警规则数据
```java
@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 消息中心数据
```java
@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 防治对象数据
```java
@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 考核任务数据
```java
@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 扩展架构
微服务支持、云原生支持、多租户支持的实现。
**代码库实现**
- **微服务支持**:数据库架构支持微服务拆分
- **云原生支持**:容器化数据库部署支持
- **多租户支持**:多租户数据隔离机制