Skip to main content

语义模型和计算模型分离

为了同时达到非常好的问答效果以及兼容用户的数据模型现状。本系统支持语义模型和计算模型分离的结构。 以下是两者的定义:

  • 语义模型:指的是我们建模要求的三范式或者雪花模型。
  • 计算模型:指的是用户实际底层的表,可以是ADS的,可以是大宽表,可以一个主题(如销售主题),在不同维度有不同的预聚合ADS表。

我们可以在建模的时候,按照三范式或者雪花模型建模。同时告诉我们的模型,在实际生成SQL的时候,按照客户的具体情况去设计。 最后的效果是:问今年销售额和问7月份销售额,实际跑的sql所对应的底表可以做到不同。

这种方式的好处是

  • 利用了用户现有的数据资产,无需为ChatBI重新准备数据。
  • 无需所有数据都从明细表中计算,可以利用到预计算的表,大幅加速了数据计算。
  • 非常容易和用户现有的报表进行数据核对,因为数据源可以做到一致。

目前一共有两种场景用到了此项技术:

  1. 语义模型 -> 大宽表
  2. 语义模型 -> 不同ADS表

1. 语义模型 -> 大宽表

大宽表指的是三范式中的实体维度都拍平放在事件表中,因此事件表的列非常多。

大宽表在计算时有一些好处

  1. 计算时候无需left join,大幅增加数据产出速度。
  2. 可以表达实体属性中的随时间可变的属性(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技术,具体文档点此查看