目标:解析现有账单表(事实表)+ 维度表的 DDL,识别出度量字段、维度外键、口径字段,作为本体建模的输入。
数仓已产出的账单表 + 维度表:
-- 账单表(事实表)
CREATE TABLE dwd_bill (
bill_id BIGINT COMMENT '账单ID',
bill_amount DECIMAL(18,2) COMMENT '账单金额', -- 度量字段
bill_count BIGINT COMMENT '账单数', -- 度量字段(恒1,SUM聚合)
region_id BIGINT COMMENT '地区外键', -- 维度外键
date_id BIGINT COMMENT '日期外键', -- 维度外键
dt STRING COMMENT '日期(yyyy-mm-dd)',
status STRING COMMENT '状态:paid/unpaid', -- 口径字段
refunded BOOLEAN COMMENT '是否退款' -- 口径字段
) COMMENT '账单事实表';
-- 维度表:地区
CREATE TABLE dim_region (
region_id BIGINT COMMENT '地区ID',
region_name STRING COMMENT '地区名(上海)',
region_group STRING COMMENT '大区(华东区)'
) COMMENT '地区维度表';
-- 维度表:日期
CREATE TABLE dim_date (
date_id BIGINT COMMENT '日期ID',
dt STRING COMMENT '日期',
month STRING COMMENT '月',
year STRING COMMENT '年'
) COMMENT '日期维度表';
| 字段类型 | 识别规则 | 示例 |
|---|---|---|
| 度量字段 | 数值型、可聚合(DECIMAL/INT,非主键非外键) | bill_amount、bill_count |
| 维度外键 | *_id 结尾、关联维度表 |
region_id、date_id |
| 口径字段 | 枚举/布尔,参与指标过滤 | status、refunded |
public class TableSchemaParser {
/** 解析表 DDL,识别三类字段 */
public ParsedTable parse(String tableName) {
List<ColumnMeta> columns = getColumns(tableName); // DESC 或 information_schema
ParsedTable t = new ParsedTable(tableName);
for (ColumnMeta c : columns) {
if (isMeasure(c)) t.measures.add(c); // 数值型 + 非主外键
else if (isDimFK(c)) t.dimFks.add(c); // *_id 结尾
else if (isCaliber(c)) t.calibers.add(c); // 枚举/布尔
}
return t;
}
private boolean isMeasure(ColumnMeta c) {
return (c.type.startsWith("DECIMAL") || c.type.startsWith("INT")
|| c.type.startsWith("BIGINT") || c.type.startsWith("DOUBLE"))
&& !c.name.endsWith("_id") && !c.isPk;
}
private boolean isDimFK(ColumnMeta c) {
return c.name.endsWith("_id");
}
private boolean isCaliber(ColumnMeta c) {
return "BOOLEAN".equals(c.type) || c.comment.contains("状态") || c.comment.contains("是否");
}
}
账单表 dwd_bill 解析结果:
度量字段:bill_amount(账单金额)、bill_count(账单数)
维度外键:region_id → dim_region、date_id → dim_date
口径字段:status(状态)、refunded(是否退款)
日期字段:dt
维度表 dim_region 解析结果:
维度字段:region_name(地区名)、region_group(大区)
这个解析结果直接喂给 02 本体建模,用于生成指标本体。