语义模型和计算模型分离
为了同时达到非常好的问答效果以及兼容用户的数据模型现状。本系统支持语义模型和计算模型分离的结构。 以下是两者的定义:
- 语义模型:指的是我们建模要求的三范式或者雪花模型。
- 计算模型:指的是用户实际底层的表,可以是ADS的,可以是大宽表,可以一个主题(如销售主题),在不同维度有不同的预聚合ADS表。
我们可以在建模的时候,按照三范式或者雪花模型建模。同时告诉我们的模型,在实际生成SQL的时候,按照客户的具体情况去设计。 最后的效果是:问今年销售额和问7月份销售额,实际跑的sql所对应的底表可以做到不同。
这种方式的好处是
- 利用了用户现有的数据资产,无需为ChatBI重新准备数据。
- 无需所有数据都从明细表中计算,可以利用到预计算的表,大幅加速了数据计算。
- 非常容易和用户现有的报表进行数据核对,因为数据源可以做到一致。
目前一共有两种场景用到了此项技术:
- 语义模型 -> 大宽表
- 语义模型 -> 不同ADS表
1. 语义模型 -> 大宽表
大宽表指的是三范式中的实体维度都拍平放在事件表中,因此事件表的列非常多。
大宽表在计算时有一些好处
- 计算时候无需left join,大幅增加数据产出速度。
- 可以表达实体属性中的随时间可变的属性(SCD)。例如会员的等级在不同时间可能是不同的,无法在简单的实体表中表达。(注意:本系统有快照实体表可以表达,但快照实体表对性能要求比较高,适用于数据量较小的情况)
以下我们展示一下,如何在保证三范式建模的情况下,配置计算时用大宽表的字段。
以下是符合三范式的一张实体表和事件表的建模:
实体表
{
"_id": "vip",
"name": "会员"
"type": "entity",
"properties": [
{ "name": "ID", "type": "ID" },
{ "name": "等级", "type": "category" }
]
}
事件表
{
"_id": "sales",
"name": "销售流水"
"type": "event",
"properties": [
{ "name": "time", "type": "timestamp" },
{ "name": "会员", "type": "object", "ref": "vip" },
{ "name": "等级", "type": "category", "is_supplementary": true, "is_projection_for": "会员_等级" }
]
}
核心就是,在事件表上,也加上等级字段,然后写上is_supplementary和is_projection_for字段。
- "is_supplementary": true,代表改字段仅用于计算,不用于问答。
- "is_projection_for"是核心字段,代表此字段和会员表里面的等级字段是一个意思。
如此配置过后,系统在生成SQL的时候可以从事件表中获取等级信息,而不是去left join对应实体表。
2. 语义模型 -> ADS表
此方式需要写javascript代码。但是非常灵活,可以做到不同的维度、查询条件组合生成的底表SQL都不一样。
此方式需要采用fromSQL技术,具体文档点此查看。