PostgreSQL针对Json设计规范

发布于:2025-08-07 ⋅ 阅读:(17) ⋅ 点赞:(0)

1. 业务域:零售实时数仓
• 核心概念

  • 原子指标(A 类)必须挂接「模型」

  • 派生指标(B 类)必须挂接「父指标」

  • 复合指标(C 类)仅做公式运算,无直接依赖
    • 维度聚合诉求:任何指标都可以声明 1..N 个维度做 GROUP BY
    • 模型关联诉求:多表 JOIN,需声明左右表及 ON 条件字段

─────────────────────────────────
2. 关键表

混淆名 职责
T_IND 指标主档
T_IND_CFG 指标配置(SELECT / WHERE / GROUP)
T_TAB 业务表
T_COL 业务表字段
T_MOD 模型主档
T_MOD_CFG 模型 JOIN 配置

─────────────────────────────────
3. JSON 定义规范(只存最小集)

3.1 GROUP 维度数组(T_IND_CFG.config_detail → GROUP)

[
  {
    "tableId": 101,     // Long  业务表ID
    "colId": 201        // Long  字段ID
  },
  {
    "tableId": 102,
    "colId": 301
  }
]

规则
① 键名统一驼峰,值为数字(避免引号)。
② 不冗余表/列中文名,不存别名——别名通过 tableId → T_TAB.alias 回表获取。
③ 数组顺序即 GROUP BY 顺序。

3.2 模型字段关系数组(T_MOD_CFG.table_field_relationship)

[
  {
    "left":  { "tableId": 101, "colId": 201 },
    "right": { "tableId": 102, "colId": 301 }
  },
  {
    "left":  { "tableId": 101, "colId": 202 },
    "right": { "tableId": 102, "colId": 302 }
]

规则
① 每对元素代表一个等值 ON 条件。
② 同样只存 ID,不存名称。

─────────────────────────────────
4. 存储设计要点

要点 说明 实现
外键弱约束 JSON 字段无法建 FK 触发器或应用层校验 tableId/colId 存在性
更新一致性 表/列改名不影响 JSON 不改 JSON,只改 T_TAB/T_COL
查询性能 列表页不拆 JSON 详情页/生成 SQL 时 JOIN 一次即可
维度复用 维度=维表字段,无字典表 通过 tableId+colId 唯一标识

─────────────────────────────────
5. 表结构原理(极简 ER)

T_IND (id, ind_type, …)  
    ├── T_IND_CFG (ind_id, cfg_type, cfg_detail)  1:N  
T_MOD (id, mod_name, …)  
    ├── T_MOD_CFG (mod_id, left_tab_id, right_tab_id, rel_type, rel_json) 1:N  
T_TAB (id, tab_alias, …)  
    ├── T_COL (id, tab_id, col_name, alias, related_tab_id, related_col_id) 1:N

• 主键全部自增 Long;所有业务码(tab_alias, col_alias)全局唯一。
• related_tab_id / related_col_id 仅用于事实表字段→维表字段导航,不做冗余存储。
• T_IND 里 dependence_model_id / dependence_indicator_id 采用「互斥空值」设计,符合当前三种指标类型,未来若出现多依赖再拆关系表。

─────────────────────────────────
6. 代码片段(解析 GROUP JSON → SQL 片段)

record DimRef(long tableId, long colId) {}
List<DimRef> dims = objectMapper.readValue(
        jsonNode.traverse(), new TypeReference<List<DimRef>>() {});
String groupBy = dims.stream()
        .map(d -> aliasMap.get(d.tableId()) + "." + colAliasMap.get(d.colId()))
        .collect(Collectors.joining(", "));

─────────────────────────────────
7. 备忘
• 禁止在 JSON 中写死中文名 → 减少 30% 存储、避免 100% 同步烦恼。
• 禁止新增任何“维度-列映射表” → 现有 T_COL.related_* 已满足需求。


网站公告

今日签到

点亮在社区的每一天
去签到