Files
Web_BLS_Heartbeat_Server/openspec/specs/db/spec.md

125 lines
5.8 KiB
Markdown
Raw Normal View History

# 数据库操作规范
## Purpose
本规范定义本服务对 PostgreSQL 的连接池配置、表结构初始化(含分区表)、分区预创建维护策略、批量写入与约束错误处理等行为。
## Requirements
### Requirement: 数据库连接管理
系统 MUST 能够建立和维护与 PostgreSQL 数据库的连接。
#### Scenario: 成功连接数据库
- **WHEN** 系统启动时
- **THEN** 应该成功连接到配置的PostgreSQL数据库
- **AND** 应该监控连接状态
#### Scenario: 数据库连接断开重连
- **WHEN** 数据库连接断开时
- **THEN** 系统应该自动尝试重连
- **AND** 重连失败时应该记录错误日志
### Requirement: 心跳数据写入
系统 MUST 能够将处理后的心跳数据写入 PostgreSQL 数据库。
#### Scenario: 写入单条心跳数据
- **WHEN** 接收到单条处理后的心跳数据时
- **THEN** 系统应该将数据写入数据库
- **AND** 返回写入结果
#### Scenario: 批量写入心跳数据
- **WHEN** 接收到批量处理后的心跳数据时
- **THEN** 系统应该使用批量写入机制将数据写入数据库
- **AND** 提高写入效率
### Requirement: 数据完整性保障
系统 MUST 保障写入数据库的心跳数据完整性。
#### Scenario: 事务管理
- **WHEN** 写入多条相关数据时
- **THEN** 系统应该使用事务确保数据一致性
- **AND** 要么全部写入成功,要么全部失败
#### Scenario: 数据约束验证
- **WHEN** 写入的数据违反数据库约束时
- **THEN** 系统应该捕获约束错误
- **AND** 记录错误日志
- **AND** 根据配置决定是否重试
### Requirement: 数据库表结构管理
系统 MUST 支持 room_status 实时状态表与心跳历史表的协同写入能力。
#### Scenario: room_status 结构与约束支持
- **WHEN** 心跳服务执行 room_status upsert 同步
- **THEN** 目标表应具备支撑 UPSERT 的唯一约束hotel_id, room_id, device_id
- **AND** 需要的同步字段应存在并可写入
### Requirement: 数组字段存储与索引
系统 MUST 支持将电力与空调子设备数据以数组列形式存储,并为指定数组列建立针对元素查询的索引。
#### Scenario: 新增数组列用于存储电力与空调子设备数据
- **WHEN** 系统初始化 v2 心跳明细表结构时
- **THEN** 表结构应包含以下新增列:
- elec_addresstext[]
- air_addresstext[]
- voltagedouble precision[]、amperedouble precision[]、powerdouble precision[]、phasetext[]、energydouble precision[]、sum_energydouble precision[]
- stateint2[]、modelint2[]、speedint2[]、set_tempint2[]、now_tempint2[]、solenoid_valveint2[]
#### Scenario: 针对数组元素的索引
- **WHEN** 对 elec_address、air_address、state、model 执行“元素包含”类查询时
- **THEN** 系统应提供 GIN 索引以优化查询
### Requirement: 数据查询支持
系统 MUST 支持基本的数据查询操作,用于监控和调试。
#### Scenario: 查询最新心跳数据
- **WHEN** 需要查询最新的心跳数据时
- **THEN** 系统应该提供查询接口
- **AND** 返回符合条件的数据
#### Scenario: 按条件查询心跳数据
- **WHEN** 需要按特定条件查询心跳数据时
- **THEN** 系统应该支持条件过滤
- **AND** 返回符合条件的数据
### Requirement: 高吞吐写入友好
系统 MUST 在高吞吐场景(约 5 万条/分钟量级)下避免单点瓶颈。
#### Scenario: 批量写入与分区裁剪
- **WHEN** 进行批量写入
- **THEN** 写入应路由到正确日分区
- **AND** 常见查询hotel_id + 时间范围)应触发分区裁剪
### Requirement: 服务运行时不得承担建库与定时分区维护
系统 MUST 仅负责数据库连接与业务写入,不在服务启动时执行数据库结构初始化,也不在进程内执行定时分区维护。
#### Scenario: 服务启动仅建立连接
- **WHEN** 服务进程启动并连接 PostgreSQL
- **THEN** 系统应只创建连接池并完成连通性检测
- **AND** 不应在运行时执行表/索引/函数等 DDL 初始化
- **AND** 不应在进程内启动分区维护定时任务
#### Scenario: 写入遇到缺分区时的运行时兜底
- **WHEN** 批量写入 `heartbeat.heartbeat_events` 遇到缺分区错误
- **THEN** 系统应基于该批次的时间范围调用 `heartbeat.ensure_partitions`
- **AND** 调用后应重试当前批次写入
- **AND** 系统不应在运行时创建或替换数据库 schema 对象
### Requirement: 建库与分区维护能力必须以外部脚本提供
系统 MUST 在仓库根目录 `SQL_Script/` 提供可被外部程序调用的建库/分区维护脚本。
#### Scenario: 提供初始化脚本
- **WHEN** 运维或其他程序需要初始化数据库结构
- **THEN** 应可使用 `SQL_Script/01_init_schema.sql``SQL_Script/run_init.js`
- **AND** 脚本应支持幂等重复执行
#### Scenario: 提供分区预创建脚本
- **WHEN** 运维或外部调度需要预创建分区
- **THEN** 应可使用 `SQL_Script/02_create_partitions.sql``SQL_Script/run_ensure_partitions.js`
- **AND** 无需启动主服务进程即可执行分区维护
## ADDED Requirements
### Requirement: 分区表新增数组列与数组元素索<E7B4A0>?系统 SHALL <20>?`heartbeat.heartbeat_events` 中新增用于存储电力与空调子设备的数组列并为指定数组列提供数组元素级查询索引<E7B4A2>?
#### Scenario: 新增数组<E695B0>?- **WHEN** 部署或升级数据库结构<E7BB93>?- **THEN** 表应包含 elec_address、air_address、voltage、ampere、power、phase、energy、sum_energy、state、model、speed、set_temp、now_temp、solenoid_valve
#### Scenario: 数组元素索引
- **WHEN** 需要按 elec_address/air_address/state/model 的数组元素进行查<E8A18C>?- **THEN** 数据库应具备 GIN 索引以优化包含类查询