跳到主要内容

Schema 反查 ​

概述 ​

Schema 反查是从真实图数据库读取当前可观察结构,并转换为 Graph SDK 公共 Schema 的过程。它用于回答“这个 Space 现在实际有哪些节点类型、边类型、属性和索引”。

反查连接的是数据库当前状态,而应用代码中保存的是期望状态。两者结合后,才能发现:

  • 数据库是否尚未应用最新 Schema;
  • 是否有人执行了未登记的手工 DDL;
  • 某次迁移是否只完成了一部分;
  • 当前后端有哪些结构无法映射到公共模型;
  • 下一次迁移可能新增、改变或删除什么。

反查不是把数据库中的所有元数据无损复制出来。Neo4j 和 Nebula 的 Schema 模型不同,部分端点、索引、约束和后端专属类型无法稳定转换为统一结构。因此,Graph SDK 返回的不只是一个 GraphSchema,而是包含完整性、警告和不可映射信息的 GraphSchemaInspection。

为什么需要反查 ​

防止期望结构与数据库漂移 ​

仅保存一份代码中的 Schema,无法证明数据库已经成功应用。部署失败、权限不足、传播延迟、手工变更和多版本应用都可能造成漂移。

反查可以在发布前后对比:

text
应用期望 Schema
        │
        ├── 比较 ──> additions / changes / removals
        │
数据库反查 Schema

为管理工具展示真实状态 ​

开发者自己实现的管理后台可以同时展示:

  • 应用声明的期望结构;
  • 数据库当前可观察结构;
  • 两者差异;
  • 后端无法反查的部分;
  • 最近检查时间和警告。

这比只展示配置文件更能帮助定位部署和权限问题。

为迁移提供输入 ​

Schema 比较和迁移计划需要一个“实际状态”输入。反查提供这个输入,但迁移系统必须结合完整性和发布历史解释结果,不能把反查缺失直接当作需要新增或删除。

识别历史库和非标准结构 ​

旧数据库可能包含不符合 Graph SDK 可移植标识符规则的标签、关系类型、属性或索引。反查会跳过无法安全映射的内容并返回警告,使管理页面仍能加载其余结构,而不是因为一个异常名称导致整个检查失败。

反查结果包含什么 ​

java
GraphSchemaInspection inspection =
    graph.manager().inspectSchema("company_knowledge");

GraphSchemaInspection 包含以下信息:

字段含义使用建议
schema转换后的公共 Schema用于展示和结构比较
complete是否完整覆盖可见结构为 false 时禁止自动破坏性决策
warnings跳过、降级或无法可靠推断的说明必须向操作者展示并记录
unsupportedMetadata后端存在但公共模型无法表达的元数据类别用于提示还需原生检查的范围
backendVersion反查时获得的后端版本,未知时为空不应假设一定存在
inspectedAtMillis反查完成时间判断结果是否过期,并用于审计

反查结果是一个时间点快照。返回之后,其他迁移或写入仍可能改变数据库结构,因此高风险操作前应重新读取,并在执行阶段处理并发变更。

基本使用方式 ​

java
GraphSchemaInspection inspection =
    graph.manager().inspectSchema("company_knowledge");

GraphSchema actual = inspection.getSchema();

if (!inspection.isComplete()) {
    for (String warning : inspection.getWarnings()) {
        System.out.println(warning);
    }
    for (String item : inspection.getUnsupportedMetadata()) {
        System.out.println("unsupported metadata: " + item);
    }
}

推荐把反查结果作为一个整体传递和保存,不要只取 getSchema() 后丢弃完整性与警告信息。

如何理解 complete ​

complete=true 表示适配器认为公共反查结果完整覆盖了它所承诺的节点、边、属性和索引元数据;它仍不代表:

  • 数据库中每条记录都符合 Schema;
  • 所有后端专属对象都已映射;
  • 索引已经在线并被查询使用;
  • 当前账号可以看到管理员才能访问的全部结构;
  • 反查完成后没有发生并发变化。

complete=false 表示已知存在无法完整恢复的结构。当前 Neo4j 和 Nebula 实现都可能因为端点或索引元数据限制返回不完整结果,因此调用方必须认真处理该字段,而不是把它当作可忽略提示。

安全原则是:

  • 不完整结果可以用于展示、诊断和保守的新增判断;
  • 不完整结果不能单独作为删除、降级或覆盖应用声明的依据;
  • 对关键结构应使用发布记录和后端原生管理查询补充验证。

warning 与 unsupported metadata ​

两类信息作用不同:

  • warning 描述本次具体发生的问题,例如某个名称无法映射、索引读取失败或端点无法推断;
  • unsupportedMetadata 描述一类公共模型当前无法表达的后端元数据,例如关系端点标签或索引集合。

管理后台应同时展示二者。只显示 complete=false 而不显示原因,用户无法判断是无害限制、权限问题还是读取失败。

建议把 warning 按以下方式处理:

类型处理方式
非法或不可移植标识符被跳过阻止自动迁移,要求人工检查原生结构
某类元数据无法反查使用版本记录或原生命令补充
索引查询失败检查账号权限、数据库版本和索引状态
类型无法精确映射核对历史值,禁止自动类型变更
空间或连接失败本次反查无效,不生成迁移计划

Neo4j 反查 ​

Neo4j 实现会读取:

  • 当前 database 中的节点 Label;
  • 节点属性名称、可观察类型和 mandatory 信息;
  • Relationship Type;
  • 关系属性名称、可观察类型和 mandatory 信息;
  • 可以通过 SHOW INDEXES 获取并映射的节点或关系索引。

已知边界 ​

Neo4j 的关系端点标签更像数据中实际形成的模式,而不是 Relationship Type 上可稳定反查和强制的公共 Schema 约束。SDK 因此使用没有端点约束的公共边类型表示反查结果,并把 relationship.endpointLabels 标记为不可映射元数据。

此外需要注意:

  • 历史数据可能让同一属性出现多种实际类型,公共 Schema 只能归一到一个可移植类型;
  • 无法映射的复杂或未知类型可能被降级为公共字符串类型,需要人工核对;
  • 不符合可移植标识符规则的 Label、关系类型、属性或索引会被跳过并记录 warning;
  • SHOW INDEXES 的可用字段和权限受 Neo4j 版本及账号影响;
  • 索引出现在反查结果中不表示索引当前一定在线或被查询计划采用。

因此,当前 Neo4j 反查结果通常不应被视为完整恢复了全部关系 Schema。

Nebula 反查 ​

Nebula 实现会读取:

  • Space 中可见的 Tag;
  • 每个 Tag 的属性和类型;
  • Space 中可见的 Edge Type;
  • 每个 Edge Type 的属性和类型。

已知边界 ​

当前 Portable Inspection 不返回完整的 Nebula 索引元数据,也不能从 Edge Schema 恢复起点和终点 Tag 约束。因此结果会将以下类别标记为不可映射:

text
edge.endpointLabels
indexes

还需要注意:

  • SHOW TAGS 或 SHOW EDGES 可见不代表 Schema 已传播到所有数据面组件;
  • DESCRIBE 返回结构不代表相关索引已完成重建;
  • 不可移植的 Tag、Edge 或属性名会被跳过并产生 warning;
  • 索引缺失于 Portable Inspection 时,不能据此判断数据库没有索引;
  • 数据库连接使用的账号可能只能看到部分 Space 或部分管理信息。

迁移涉及 Nebula 索引时,应结合 Schema 发布记录和原生索引查询,不要只依赖公共反查结果。

从反查到差异比较 ​

标准流程如下:

java
GraphSchemaInspection inspection =
    graph.manager().inspectSchema("company_knowledge");

GraphSchemaDiff diff = GraphSchemaComparator.compare(
    expectedSchema,
    inspection.getSchema());

GraphSchemaMigrationPlan plan = GraphSchemaMigrationPlanner.plan(
    expectedSchema,
    inspection.getSchema());

在解释差异前,应先检查:

  1. 反查是否完整;
  2. 是否存在被跳过的标识符;
  3. 是否有索引或端点元数据无法映射;
  4. 结果是否来自正确的后端和 Space;
  5. 反查时间是否足够新;
  6. 上次成功发布记录是否与数据库状态一致。

只有这些前提满足,迁移计划才具有足够可信度。

推荐的反查流程 ​

1. 确认目标 ​

根据可信的租户、知识库和环境映射解析 GraphStore 与 Space。不要让客户端直接决定需要反查的管理目标。

2. 检查连接和能力 ​

健康检查只能证明基础连通性;还应确认当前账号有读取 Schema 元数据的权限,并了解目标后端的 inspection 能力限制。

3. 执行反查 ​

记录请求 ID、后端、Space、开始时间和结果。失败时保留统一错误码,不要把空 Schema 当作成功结果。

4. 展示完整结果 ​

同时展示结构、complete、warnings、unsupported metadata 和检查时间。不要在 UI 中只渲染节点/边列表。

5. 与期望和历史记录对比 ​

期望 Schema 用于判断发布目标,历史记录用于弥补后端反查盲区,当前反查用于发现真实漂移。

6. 补充原生检查 ​

当迁移涉及索引、约束、端点或后端专属类型时,执行只读的原生管理查询进行补充。补充结果应和 Portable Inspection 分开标注,避免误认为可跨后端复用。

7. 生成迁移建议 ​

不完整反查只能生成保守建议。任何 removal、类型覆盖或约束替换都应进入人工审批。

适用场景 ​

应用启动检查 ​

可以在启动或 readiness 流程中确认 Space 和关键结构是否存在。但不建议每个实例启动时自动执行破坏性迁移,也不应让短暂的 Schema 传播延迟触发重复 DDL。

发布前迁移预览 ​

在 CI/CD 或发布控制面中反查目标环境,展示差异和风险,审批后再执行兼容变更。

Schema 管理后台 ​

展示期望结构、实际结构、差异、警告和后端限制。用户可以据此决定迁移,而不是直接编辑数据库。

漂移检测 ​

周期性读取实际 Schema,与最后发布版本比较,发现手工 DDL、失败迁移或未知索引。无变化时无需通知;出现可操作差异时再告警。

故障排查 ​

当写入出现“属性不存在”、查询出现“索引不存在”或抽取结果无法入图时,反查可以帮助确认目标 Space 的 Schema 是否真的就绪。

不应如何使用反查 ​

  • 不要把反查结果直接覆盖代码中的期望 Schema;
  • 不要因为某项未反查到就自动创建、删除或重建;
  • 不要忽略 complete=false 和 warnings;
  • 不要把反查当作全量数据质量扫描;
  • 不要用每次业务请求实时反查代替版本和缓存;
  • 不要假设反查返回的类型、索引和约束在所有后端完全等价;
  • 不要使用高权限管理账号执行所有普通查询,只为方便反查。

缓存与并发变更 ​

Schema 通常变化较少,管理后台可以短期缓存反查结果,但必须展示检查时间并提供主动刷新。以下时机会使缓存失效:

  • 成功应用 Schema 后;
  • 索引创建、重建或删除后;
  • Space 切换或连接配置更新后;
  • 数据库升级后;
  • 检测到外部 DDL 或发布漂移后。

如果反查与迁移之间间隔较长,数据库结构可能已被其他操作者改变。高风险迁移应在执行前重新反查并重新生成差异,而不是使用过期计划。

常见问题 ​

为什么 isComplete 总是 false? ​

这通常是已知后端元数据无法映射造成的,不一定表示反查失败。应查看 warnings 和 unsupported metadata:Neo4j 主要缺少可靠的关系端点标签,Nebula 当前主要缺少完整索引和端点信息。

反查没有索引,是否应该重新创建? ​

不能直接这样判断。特别是 Nebula 当前 Portable Inspection 不返回完整索引元数据。应查询发布记录或使用原生管理命令确认。

反查 Schema 与实际数据为什么不同? ​

Schema 反查读取结构元数据,不扫描每个节点和边。历史数据可能缺属性、使用旧值或形成未声明模式,需要单独的数据质量检查。

能否使用反查结果自动生成 UI? ​

可以用于生成基础结构展示,但业务展示名称、说明、默认值和枚举等工具元数据可能只存在于期望 Schema 中。更合理的方式是以期望 Schema 提供产品元数据,以反查结果显示数据库状态和差异。

后端版本为什么可能为空? ​

backendVersion 是可选信息。适配器或当前权限无法可靠获取时会返回空字符串,上层不能把它当作必填字段。

生产检查清单 ​

  • 是否确认了正确的后端、环境和 Space;
  • 当前账号是否具备读取 Schema 元数据的最小权限;
  • 是否保存 complete、warnings 和 unsupported metadata;
  • 是否明确展示反查时间,避免使用过期结果;
  • 是否将连接失败与“空 Schema”严格区分;
  • 是否针对不可移植标识符阻止自动迁移;
  • 是否使用发布记录补充索引、端点和版本信息;
  • 是否在破坏性操作前执行原生只读核验;
  • 是否避免基于不完整结果自动生成删除操作;
  • Schema 应用后是否重新反查并执行真实读写验证;
  • 是否对周期性漂移检测设置合理频率和告警策略。

反查提供的是数据库当前可观察结构,而不是唯一事实来源。可靠的 Schema 治理需要同时维护期望定义、发布历史、反查结果和真实数据验证。