Files
railwaysystem/docs/development/dms-r3/09_database_mapping_proposal.md
T

7.6 KiB
Raw Blame History

09 数据库持久化模型方案比选与设计基线 (Database Mapping Proposal)

设计红线:本轮仅做架构比选与实体设计,禁止执行任何 DDL 脚本或修改生产数据库。 设计原则:面向未来多锁扩展与多厂商接入,保持本地宿舍台账的纯粹性,业务授权与硬件异步对账分层治理。


1. 外部资源映射模型比选 (RESOURCE_MAPPING_RECOMMENDATION)

1.1 映射关系现实挑战

  1. 一个房间可能安装多把锁:如公寓入户门锁与套内自习室/卧室锁,单一房间可能绑定 0、1 或多把智能门锁。
  2. 外部厂商多变性:DMS 属于第三方 SaaS/IoT 平台,未来房建公寓段若自建门禁或改用国铁集团集采设备,字段名与标识均可能改变。
  3. 资源解绑与重绑需求:房间门锁损坏更换后,仅涉及设备 SN 变更,不应引起本地宿舍主记录的历史数据污染。

1.2 两种设计方案对比

评估维度 方案一:在 train_dormitory_info 直接加列 方案二:独立 train_external_resource_mapping 表 (推荐)
表结构改动 在宿管表直接加 dms_place_id, dms_lock_id, dms_lock_sn 等 物理宿舍表保持零污染;新建独立的外部资源映射关联表
一房多锁支持 无法支持(单行只能记录一把锁的 SN 和 ID) 天然支持(一个 dorm_id 可对应多行锁具映射记录)
多厂商与扩展性 差(换厂商需继续加字段,如 hik_channel_id) 优秀(通过 vendor_code 区分不同厂商,复用通用映射模型)
设备更换生命周期 弱(直接覆写破坏审计历史) 强(可标记旧锁为 DEPRECATED,新增新锁映射)
迁移与实施成本 极低 低(新增一张轻量级关联表)

1.3 外部资源映射推荐方案结论

采纳方案二:建立独立的外部资源映射模型。

  • 概念模型结构设计:
    train_external_resource_mapping
    ├── mapping_id          BIGINT (主键)
    ├── local_resource_type VARCHAR(32) ('DORMITORY_ROOM', 'DORMITORY_LOCK')
    ├── local_resource_id   VARCHAR(32) (关联本地 dorm_id)
    ├── vendor_code         VARCHAR(32) ('DMS_IOT')
    ├── external_project_id BIGINT      (DMS 租户 projectId)
    ├── external_parent_id  BIGINT      (DMS 楼栋/楼层 ID)
    ├── external_place_id   BIGINT      (DMS 房间 placeId)
    ├── external_device_id  BIGINT      (DMS 门锁 lockId)
    ├── hardware_sn         VARCHAR(64) (门锁硬件 SN / hardwareId)
    ├── mapping_status      SMALLINT    (1: 已绑定有效, 0: 待核对/失效)
    ├── last_sync_time      TIMESTAMP   (最近一次从 DMS 同步元数据的时间)
    └── [标准审计列]
    

2. 门禁授权与操作模型三大方案深度比选

2.1 方案架构与评估矩阵

评估维度 方案 A: 改造并继续扩展 train_dorm_auth 方案 B: train_dorm_auth 收敛为业务授权 + 独立 train_external_operation (推荐) 方案 C: 新建 train_door_authorization + train_external_operation
模型设计说明 在现有的 train_dorm_auth 表中强行塞入 lock_id, dms_key_id, operation_id, password 等列 保留并对齐数据库 V2 的 train_dorm_auth 作为门禁授权主表;新建 train_external_operation 承载所有异步轮询与重试流水 彻底废除 train_dorm_auth,重新设计全套中立命名的门禁授权与外部操作表
一期开发复杂度 低(改单表) 适中(改主表结构 + 建流水表) 略高(需处理原有表废弃与实体完全重构)
语义与职责清晰度 严重混乱(业务授权与设备单次请求纠缠,无法表达异步过程) 良好(业务授权状态与设备异步任务彻底解耦) 极优(概念完全脱离人脸/宿舍局限)
一房多锁支持能力 无法支持(accommodation_id 唯一约束导致无法为同一个住宿下发多把锁) 支持(主表唯一约束调整为 (accommodation_id, device_mapping_id)) 支持(原生复合设计)
异步状态与重试审计 丢失历史(每次重试都会覆写 last_error 和 operation_id) 完整保留(流水表每次调用追加一行,多次轮询与超时全量追踪) 完整保留
历史兼容与代码改动 兼容性最高,但长期技术负债巨大 平衡性最佳(沿用 V2 数据库迁移成果,仅修正 Java 实体脱节) 需调整较多已有引用类名

3. 推荐采纳模型设计基线 (DOOR_AUTH_MODEL_RECOMMENDATION)

综合考虑沈阳房建公寓段学员管理系统目前所处的正式 Release 阶段与 V2 数据库已经上线的实际情况,推荐采纳【方案 B】(业务授权主表收敛 + 异步操作流水表解耦)。

3.1 实体一:门禁业务授权主模型 (TrainDormAuth / 业务授权主表)

承担职责:表达某个学员住宿事实在某把门锁上的长期通行权限状态。

  • auth_id: BIGINT, PK
  • accommodation_id: BIGINT, 外键关联 train_accommodation (业务事实真源)
  • mapping_id: BIGINT, 关联 train_external_resource_mapping (目标门锁)
  • credential_type: VARCHAR(20) ('ONLINE_PASSWORD', 'ONLINE_CARD')
  • credential_mask: VARCHAR(50) (脱敏凭据摘要,如 '34' 或 '244B')
  • external_key_id: BIGINT (DMS 返回的钥匙实体 ID,用于注销撤权)
  • auth_start: TIMESTAMP (权限生效起始时间)
  • auth_end: TIMESTAMP (权限失效截止时间)
  • auth_status: SMALLINT (0:待下发, 1:下发中, 2:已生效, 3:下发失败, 4:撤销中, 5:已注销, 6:撤销失败)
  • grant_version: INT (授权版本号,换房或重新下发时自增,保障本地幂等)
  • [标准审计列] (create_by, create_time, update_by, update_time)

3.2 实体二:外部异步操作流水模型 (TrainExternalOperation / 异步操作流水表)

承担职责:跟踪向 DMS 派发的每一次具体 HTTP 异步任务的生命周期与轮询轨迹。

  • operation_local_id: BIGINT, PK
  • auth_id: BIGINT, 外键关联授权主表
  • business_action: VARCHAR(32) ('GRANT_PASSWORD', 'REVOKE_PASSWORD', 'GRANT_CARD', 'REVOKE_CARD')
  • vendor_code: VARCHAR(32) ('DMS_IOT')
  • dms_operation_id: VARCHAR(64) (DMS 返回的 32 位 UUID 操作流水号)
  • dms_request_type: INT (DMS 数字请求类型,如 1=下发密码, 3=删除密码)
  • hardware_id: VARCHAR(64) (门锁硬件 SN)
  • operation_status: VARCHAR(20) ('ACCEPTED', 'UNDONE', 'SUCCESS', 'FAILED', 'TIMEOUT')
  • poll_count: INT (已轮询次数,初始为 0,上限通常为 3)
  • next_poll_time: TIMESTAMP (调度器下次拉取状态的时间,初始为 request_time + 10s)
  • request_time: TIMESTAMP (向 DMS 发起请求的时间)
  • complete_time: TIMESTAMP (DMS 返回终态的时间)
  • error_code & error_message: VARCHAR (错误摘要)
  • sanitized_response: VARCHAR(1000) (脱敏后的响应快照)
  • [标准审计列]

4. 实施阶段演进建议

在后续 R.3B 实施阶段,数据访问层的演进步骤建议为:

  1. 第一步:重构修复 Java 实体类 TrainDormAuth.java,彻底移除已弃用的 student_id, plan_id, dorm_id 字段,使其与已存在的 Kingbase 物理表字段完全对齐。
  2. 第二步:创建 train_external_resource_mapping 与 train_external_operation 迁移脚本(遵循系统标准 Liquibase/Flyway 规范)。
  3. 第三步:通过 Spring Data / MyBatis-Plus 完成三表关联映射。