Files
railwaysystem/docs/codebase-audit/13_live_database_snapshot.md
T
wangzhibiao fb00f67d3b docs(审计): 完成Phase 0工程与数据库基线核验
记录当前Git开发基线、Kingbase真实表结构、培训数据与权限状态。

补充数据库与代码差异、只读兼容性验证及PRD V1.0核心对象映射,未包含业务代码或数据库修改。
2026-09-14 00:36:53 +08:00

406 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 0:Kingbase 实时数据库快照
> 快照时间:数据库返回 `2026-09-14 00:07:58`
> 连接方式:复用 `application-druid.yml` 的 Kingbase JDBC配置,通过既有 SSH/Tailscale隧道连接 `127.0.0.1:4321`。
> 安全措施:JDBC连接开启只读事务,所有探测仅执行 `SELECT`、`SHOW` 和系统目录查询;最后执行 rollback并关闭连接。未输出口令、用户明细或培训人员明细。
## 1. 数据库基本信息
| 项目 | 实际值 |
| --- | --- |
| 数据库产品版本 | `KingbaseES V009R003C018` |
| JDBC驱动 | Kingbase8 JDBC Driver `V008R006B0001`;项目Maven坐标版本为 8.6.0 |
| database | `training` |
| schema | `public` |
| 当前用户 | `kingbase` |
| `database_mode` | `mysql` |
| 底层兼容版本设置 | `server_version=12.1` |
| 简单 `SELECT 1` | 成功 |
## 2. 14张培训表是否存在及行数
| 表名 | 是否存在 | schema | 精确行数 |
| --- | --- | --- | ---: |
| `train_teacher` | 是 | public | 1 |
| `train_student` | 是 | public | 0 |
| `train_course` | 是 | public | 0 |
| `train_class_plan` | 是 | public | 0 |
| `train_dormitory_info` | 是 | public | 0 |
| `train_dorm_auth` | 是 | public | 0 |
| `train_classroom_info` | 是 | public | 0 |
| `train_training_site` | 是 | public | 0 |
| `train_class_report` | 是 | public | 0 |
| `train_electronic_board` | 是 | public | 0 |
| `train_student_checkin` | 是 | public | 0 |
| `train_score_info` | 是 | public | 0 |
| `train_study_duration` | 是 | public | 0 |
| `train_student_portrait` | 是 | public | 0 |
`public` 中所有以 `train_` 开头的表恰好就是这 14 张,没有发现额外培训表。
## 3. 真实表结构
说明:`N` 表示 NOT NULL,`Y` 表示允许 NULL;未标默认值即无默认。`IDENTITY` 均为 `GENERATED BY DEFAULT AS IDENTITY`。实际时间类型为 Kingbase `timestamp`,实际小整数类型为 `smallint`。
### 3.1 `train_teacher`
```text
t_id varchar(32) N PK
t_name varchar(30) N
t_gender char(2) Y
t_birth date Y
t_department varchar(50) N
t_title varchar(30) Y
t_phone varchar(20) Y
t_email varchar(50) Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`t_id`);无其他 UNIQUE。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_teacher_modify` 在 UPDATE前调用 `func_train_update_modifytime()`。
### 3.2 `train_student`
```text
s_id varchar(32) N PK
s_name varchar(30) N
s_gender char(2) Y
s_birth date Y
s_department varchar(50) N
s_major varchar(50) N
s_class varchar(30) Y
s_phone varchar(20) Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`s_id`)。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_student_modify` 更新 `update_time`。
### 3.3 `train_course`
```text
c_id varchar(32) N PK
c_name varchar(100) N
c_type varchar(30) Y
c_duration integer Y
teaching_objective text Y
course_content text Y
attach_doc text Y
attach_video text Y
attach_model_link text Y
model_resource_ids text Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`c_id`)。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_course_modify` 更新 `update_time`。
### 3.4 `train_class_plan`
```text
plan_id varchar(32) N PK
plan_name varchar(100) N
c_id varchar(32) N FK -> train_course.c_id
start_time timestamp N
end_time timestamp N
train_address varchar(100) Y
t_id varchar(32) N FK -> train_teacher.t_id
recruit_num integer Y
apply_condition text Y
plan_status smallint Y DEFAULT 0
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`plan_id`)。
- 外键:`fk_classplan_course`、`fk_classplan_teacher`,默认 NO ACTION。
- 索引:只有主键唯一索引;未发现 `c_id`、`t_id` 的独立索引。
- 触发器:`trig_train_classplan_modify` 更新 `update_time`。
### 3.5 `train_dormitory_info`
```text
dorm_id varchar(32) N PK
dorm_building varchar(50) Y
dorm_room varchar(30) N
bed_total integer Y
bed_used integer Y DEFAULT 0
lock_device_sn varchar(64) Y
dorm_status smallint Y DEFAULT 1
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`dorm_id`);UNIQUE(`dorm_building`,`dorm_room`)。
- 外键:无。
- 索引:主键与房间组合唯一索引,无额外非唯一索引。
- 触发器:`trig_train_dorminfo_modify` 更新 `update_time`。
### 3.6 `train_dorm_auth`
```text
auth_id bigint N PK, IDENTITY
student_id varchar(32) N FK -> train_student.s_id
plan_id varchar(32) N FK -> train_class_plan.plan_id
dorm_id varchar(32) N FK -> train_dormitory_info.dorm_id
bed_no varchar(20) Y
face_sync_status smallint Y DEFAULT 0
auth_start timestamp Y
auth_end timestamp Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`auth_id`);UNIQUE(`student_id`,`plan_id`)。
- 外键:`fk_dormauth_stu`、`fk_dormauth_plan`、`fk_dormauth_dorm`。
- 索引:主键与参训人组合唯一索引,无其他非唯一索引。
- 生成:内部 identity序列 `train_dorm_auth_auth_id_seq`。
- 触发器:`trig_train_dormauth_modify` 更新 `update_time`。
### 3.7 `train_classroom_info`
```text
class_room_id varchar(32) N PK
room_name varchar(60) N
room_location varchar(100) Y
capacity integer Y
room_status smallint Y DEFAULT 1
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`class_room_id`)。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_classroom_modify` 更新 `update_time`。
### 3.8 `train_training_site`
```text
site_id varchar(32) N PK
site_name varchar(80) N
site_location varchar(100) Y
capacity integer Y
site_device text Y
site_status smallint Y DEFAULT 1
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`site_id`)。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_trainsite_modify` 更新 `update_time`。
### 3.9 `train_class_report`
```text
report_id bigint N PK, IDENTITY
plan_id varchar(32) N FK -> train_class_plan.plan_id
student_id varchar(32) N FK -> train_student.s_id
report_way smallint Y
report_device_sn varchar(64) Y
report_time timestamp Y
report_status smallint Y DEFAULT 0
alloc_dorm_id varchar(32) Y FK -> train_dormitory_info.dorm_id
alloc_classroom_id varchar(32) Y FK -> train_classroom_info.class_room_id
alloc_site_id varchar(32) Y FK -> train_training_site.site_id
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
```
- 主键/唯一:PK(`report_id`);UNIQUE(`plan_id`,`student_id`)。
- 外键:计划、学员、宿舍、教室、实训场地共5个外键。
- 索引:主键与计划/学员唯一索引,无其他非唯一索引。
- 生成:identity序列 `train_class_report_report_id_seq`。
- 触发器:无。
### 3.10 `train_electronic_board`
```text
board_id varchar(32) N PK
board_sn varchar(64) N UNIQUE
bind_classroom_id varchar(32) Y FK -> train_classroom_info.class_room_id
bind_plan_id varchar(32) Y FK -> train_class_plan.plan_id
board_ip varchar(50) Y
board_content varchar(500) Y
board_playmode smallint Y DEFAULT 1
support_checkin_type varchar(30) Y
board_status smallint Y DEFAULT 1
last_heartbeat timestamp Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`board_id`);UNIQUE(`board_sn`)。
- 外键:教室、开班计划。
- 索引:主键与设备序列号唯一索引,无其他非唯一索引。
- 触发器:`trig_train_board_modify` 更新 `update_time`。
### 3.11 `train_student_checkin`
```text
checkin_id bigint N PK, IDENTITY
plan_id varchar(32) N FK -> train_class_plan.plan_id
c_id varchar(32) N FK -> train_course.c_id
student_id varchar(32) N FK -> train_student.s_id
board_id varchar(32) Y FK -> train_electronic_board.board_id
checkin_way smallint Y
checkin_time timestamp Y
checkin_status smallint Y
lesson_start_time timestamp Y
lesson_end_time timestamp Y
```
- 主键/唯一:PK(`checkin_id`);UNIQUE(`plan_id`,`c_id`,`student_id`,`lesson_start_time`)。
- 外键:计划、课程、学员、班牌。
- 索引:主键与旧“课次+学员”组合唯一索引,无其他非唯一索引。
- 生成:identity序列 `train_student_checkin_checkin_id_seq`。
- 触发器:无。
### 3.12 `train_score_info`
```text
score_id bigint N PK, IDENTITY
plan_id varchar(32) Y FK -> train_class_plan.plan_id
c_id varchar(32) Y FK -> train_course.c_id
student_id varchar(32) Y FK -> train_student.s_id
course_score numeric(5,2) Y
train_score numeric(5,2) Y
exam_score numeric(5,2) Y
source_type smallint Y
source_system varchar(50) Y
import_time timestamp Y DEFAULT CURRENT_TIMESTAMP
```
- 主键/唯一:PK(`score_id`);UNIQUE(`plan_id`,`c_id`,`student_id`)。
- 外键:计划、课程、学员。
- 索引:主键与计划/课程/学员唯一索引,无其他非唯一索引。
- 生成:identity序列 `train_score_info_score_id_seq`。
- 触发器:无。
### 3.13 `train_study_duration`
```text
dur_id bigint N PK, IDENTITY
student_id varchar(32) Y FK -> train_student.s_id
plan_id varchar(32) Y FK -> train_class_plan.plan_id
c_id varchar(32) Y FK -> train_course.c_id
device_type varchar(50) Y
start_time timestamp Y
end_time timestamp Y
study_seconds integer Y
sync_time timestamp Y DEFAULT CURRENT_TIMESTAMP
```
- 主键/唯一:PK(`dur_id`);无其他 UNIQUE。
- 外键:学员、计划、课程。
- 索引:只有主键唯一索引。
- 生成:identity序列 `train_study_duration_dur_id_seq`。
- 触发器:无。
### 3.14 `train_student_portrait`
```text
portrait_id bigint N PK, IDENTITY
student_id varchar(32) N FK -> train_student.s_id
plan_id varchar(32) N FK -> train_class_plan.plan_id
total_study_hour numeric(8,2) Y
avg_score numeric(5,2) Y
checkin_rate numeric(5,2) Y
label_tag text Y
portrait_content text Y
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
```
- 主键/唯一:PK(`portrait_id`);UNIQUE(`student_id`,`plan_id`)。
- 外键:学员、计划。
- 索引:主键与学员/计划唯一索引,无其他非唯一索引。
- 生成:identity序列 `train_student_portrait_portrait_id_seq`。
- 触发器:无。
## 4. 主键、外键、索引与触发器汇总
- 14张表均有主键。
- 6张数字主键表均为 `bigint GENERATED BY DEFAULT AS IDENTITY`,JDBC元数据返回 `IS_AUTOINCREMENT=YES`;驱动返回 `supportsGetGeneratedKeys=true`。由于禁止写入,本次没有实际 INSERT验证回填。
- 8张字符串主键表没有默认生成器,仍由应用/用户提供业务编号。
- 实际有 24个培训外键关系,孤儿统计均为 0;当前除教师外各表为空,不能用现有数据证明复杂关联行为。
- 除主键和7组业务唯一约束外,`pg_indexes` 未发现额外非唯一索引;多个外键列没有独立索引。
- 9张有 `update_time` 的主数据表通过 `func_train_update_modifytime()` 触发器在 UPDATE前更新时间。
## 5. 数据安全统计
- 唯一现有培训业务数据:`train_teacher` 1行;未输出姓名、电话、邮箱或主键值。
- 8张字符串主键表均无 NULL或重复主键;其中7张为空,教师表1行。
- 24组已建外键关系的孤儿数均为0。
- `train_score_info` 为0行,当前没有真实成绩需要迁移。
- `train_class_plan`、`train_student`、报到、住宿、签到、时长、画像均为0行。
- 教师记录的 `create_time`、`update_time` 确实含非零时分秒;其他业务时间字段因对应表为空,无法用数据确认。
## 6. 关键 `sys_*` 表真实状态
以下均指明确限定的 `public.sys_*`,避免与 Kingbase系统视图混淆。
| 表 | 是否存在 | 行数 | 主要列是否覆盖若依模型 |
| --- | --- | ---: | --- |
| `public.sys_user` | 是 | 1 | 是:`user_id`至`pwd_update_date`齐全 |
| `public.sys_role` | 是 | 0 | 是:`role_id`、`role_key`、`data_scope`等齐全,但无数据 |
| `public.sys_menu` | 是 | 106 | 是:路由、component、perms、menu_type等齐全 |
| `public.sys_user_role` | 是 | 20 | 列齐全,但关系数据异常 |
| `public.sys_role_menu` | 是 | 170 | 列齐全,但关系数据异常 |
| `public.sys_dept` | 是 | 15 | 列齐全 |
| `public.sys_role_dept` | 是 | 0 | 列齐全 |
| `public.sys_config` | 是 | 0 | 列齐全,但无应用配置数据 |
| `public.sys_dict_type` | 是 | 44 | 列齐全 |
| `public.sys_dict_data` | 是 | 500 | 列齐全 |
| `public.sys_job` | 是 | 0 | 列齐全 |
| `public.sys_job_log` | 是 | 0 | 列齐全 |
关系完整性统计:
- `public.sys_user_role` 20行,其中18行引用不存在的应用用户,20行全部引用不存在的应用角色。
- `public.sys_role_menu` 170行,全部引用不存在的应用角色;另有9行引用不存在的菜单。
- `public.sys_role` 为0行,因此实时库没有可识别的培训角色或普通应用角色。
## 7. Kingbase系统视图同名冲突
当前隐式搜索顺序为:
```text
sys -> pg_catalog -> sys_catalog -> public
```
Kingbase在 `sys_catalog` 中也提供 `sys_user`、`sys_role`、`sys_config` 视图。现有若依 Mapper 使用未限定表名,实测:
- `select ... user_id ... from sys_user` 命中系统视图并报 `user_id` 不存在。
- `select ... role_id ... from sys_role` 命中系统视图并报 `role_id` 不存在。
- `select ... config_id ... from sys_config` 命中系统视图并报 `config_id` 不存在。
因此“public表结构与Entity/Mapper列名一致”仍不足以证明若依系统功能可用;schema解析冲突是独立阻塞项。