Files
Web_BLS_Heartbeat_Server/docs/db-guid-pk-and-service-mask-index-plan.md
XuJiacheng 41301f9ce5 feat: 实现GUID主键与service_mask索引改造
- 将主键从自增id改为GUID格式并添加格式校验
- 为service_mask添加表达式索引优化首位查询性能
- 更新相关文档说明改造方案与验证步骤
- 添加统计模块记录数据库写入与Kafka消费量
- 重构Redis心跳协议改用LIST类型存储项目状态
- 修复部署脚本中的服务名称不一致问题
2026-01-17 18:37:44 +08:00

2.2 KiB
Raw Blame History

GUID 主键与 service_mask 索引改造实施方案

目标

  • heartbeat.heartbeat_events 的主键从自增 id 改为 GUID32 位无连字符 HEX 字符串)。
  • service_mask 的“首位(最低位)判断”新增表达式索引 idx_service_mask_first_bit,用于优化常见 bit 查询。
  • 说明:你会删除现有数据库,因此不提供在线迁移流程,仅提供可重建的初始化脚本与验证步骤。

方案概述

1) 主键GUID

  • 表字段 guid 使用 varchar(32) 并设置默认值 replace(gen_random_uuid()::text, '-', '')
  • 通过 CHECK (guid ~ '^[0-9a-f]{32}$') 约束输入格式为 32 位小写 HEX。
  • 分区表使用组合主键 PRIMARY KEY (ts_ms, guid) 以满足 PostgreSQL 分区唯一约束要求(主键/唯一约束需包含分区键)。

2) service_mask 首位查询表达式索引

  • 在父表创建索引:
    • CREATE INDEX idx_service_mask_first_bit ON heartbeat.heartbeat_events ((service_mask & 1));
  • 在按天分区创建索引:
    • idx_<partition>_service_mask_first_bit

实施步骤(重建式)

  1. 删除旧数据库/旧 schema你将执行
  2. 执行建表脚本:
    • scripts/db/010_heartbeat_schema.sql
    • scripts/db/020_partitioning_auto_daily.sql
  3. 启动服务或执行 npm run db:apply 进行初始化。
  4. 执行验证项:
    • 确认 heartbeat.heartbeat_events.guidvarchar(32) 且存在默认值
    • 确认存在 idx_service_mask_first_bit
    • 确认分区新建后存在 idx_<partition>_service_mask_first_bit

风险评估

  • GUID 默认生成依赖 pgcrypto 扩展:脚本已包含 CREATE EXTENSION IF NOT EXISTS pgcrypto;,但执行账号需要具备安装扩展权限。
  • 分区表主键约束限制:无法实现“父表仅 guid 作为主键约束”,因此使用 (ts_ms, guid) 的组合主键。
  • 表达式索引的表达式匹配:业务查询需要匹配索引表达式(详见 checklist否则无法命中索引。

回滚步骤(重建式)

  1. 停止服务写入。
  2. DROP SCHEMA heartbeat CASCADE;(或删除数据库)。
  3. 使用回滚版本的 SQL 脚本重新创建(例如回退到 id bigserial 版本的脚本)。
  4. 重新启动服务并验证写入与查询。