语义视图(SEMANTIC VIEW)在数据库内声明一层面向业务的语义模型,通过TABLES、RELATIONSHIPS、DIMENSIONS和METRICS子句组织底层物理表、表间关系、业务维度和指标。查询语义视图时,您只需指定维度名和AGG(指标名),Hologres会自动完成表裁剪、最小JOIN与先聚合后关联,避免明细表JOIN后再聚合导致的指标重复放大,同时生成结构化的YAML模型,供BI工具与AI Agent(NL2SQL)读取业务语义。本文为您介绍SEMANTIC VIEW的语法、查询方式、内省方法和使用限制。
SEMANTIC VIEW当前处于Beta阶段,仅Hologres V5.0.0及以上版本支持。
背景信息
应用场景
统一指标口径:将
total_revenue固定定义为sum(o.amount),避免同一指标存在多种计算口径。降低查询复杂度:业务人员只需使用维度和指标查询数据,无需理解星型模型的物理表与JOIN关系。
避免重复计数:一对多JOIN后再聚合时,金额、计数等指标被放大的问题由引擎自动规避。
AI与NL2SQL友好:结构化的YAML模型为AI Agent提供业务语义上下文。
原理
查询Semantic View时,引擎不会先将所有物理表JOIN后再聚合,而是按以下步骤改写查询:
为每个被引用的指标构造最小JOIN子树,只关联必要的表,无关表自动裁剪。
将来源、粒度、JOIN树一致的指标合并为一个metric group,共用一次扫描与聚合。
每个metric group在相同的输出维度上先独立聚合。
存在多个metric group时,选取粒度最细的metric group作为主结果域,其余metric group按全部输出维度做NULL-safe
LEFT JOIN拼接。
当某个指标的归属表会被JOIN放大(fan-out)时,引擎会先按“输出维度+归属表主键”去重,再回表聚合,保证同一条记录对同一输出维度至多贡献一次。
对于无法安全判断语义的查询形态(关系路径歧义、同一父表下存在多条独立的many-side分支),引擎直接报错拒绝,不返回可能错误的结果。
开关与可观测性
SEMANTIC VIEW的查询能力与调试输出由以下GUC参数控制。
GUC参数 | 默认值 | 说明 |
|
| 是否启用Semantic View查询能力。关闭后,查询语义视图会按普通表解析,并报错 |
|
| 是否通过 |
更多GUC参数的说明,请参见GUC参数。
您可以通过如下命令开启或关闭调试输出。
SET hg_semantic_view_rewrite_debug = on; -- 排查时开启
RESET hg_semantic_view_rewrite_debug;创建Semantic View
语法
创建和删除语义视图的语法格式如下。
CREATE SEMANTIC VIEW [IF NOT EXISTS] [schema.]view_name
TABLES ( alias AS [schema.]table_name [PRIMARY KEY (col1[, ...])] , ... )
[RELATIONSHIPS ( [rel_name AS] from_alias(col[, ...]) REFERENCES to_alias[(col[, ...])] , ... )]
[DIMENSIONS ( owner_alias.dim_name AS <expression> [COMMENT = '说明'] , ... )]
[METRICS ( owner_alias.metric_name AS <aggregate_expression> [COMMENT = '说明'] , ... )]
[COMMENT = '视图说明'];
DROP SEMANTIC VIEW [IF EXISTS] [schema.]view_name;参数说明如下。
参数 | 说明 |
| 语义视图的名称,可通过 |
| 声明参与建模的物理表,格式为 |
| 声明表间关系,格式为 |
| 声明业务维度,格式为 |
| 声明业务指标,格式为 |
| 维度表达式,为单个物理alias的行级表达式,支持列、常量、系统内置标量函数与运算符、 |
| 指标聚合表达式。支持的聚合函数为 |
| 视图、维度或指标的说明。 |
示例
以下示例基于已存在的public.orders与public.customers表,创建名为sales_sv的语义视图。
CREATE SEMANTIC VIEW sales_sv
TABLES (
o AS public.orders PRIMARY KEY (order_id),
c AS public.customers PRIMARY KEY (customer_id)
)
RELATIONSHIPS ( rel_oc AS o(customer_id) REFERENCES c(customer_id) )
DIMENSIONS (
o.status_dim AS o.status,
c.city_dim AS c.city COMMENT = '客户城市'
)
METRICS (
o.total AS sum(o.amount) COMMENT = '订单金额',
o.order_count AS count(*),
c.credit AS sum(c.credit_limit)
)
COMMENT = '销售分析语义视图';查询Semantic View
查询语义视图时,指标必须使用AGG(指标名)包裹,维度可直接引用并写入GROUP BY。查询示例如下。
-- 分组聚合
SELECT city_dim, AGG(total), AGG(credit) FROM sales_sv GROUP BY city_dim;
-- 全局聚合(无需 GROUP BY)
SELECT AGG(total), AGG(order_count) FROM sales_sv;
-- WHERE 过滤维度(只作过滤、不进入输出粒度)
SELECT city_dim, AGG(total) FROM sales_sv WHERE status_dim = 'completed' GROUP BY city_dim;
-- HAVING / ORDER BY / LIMIT
SELECT city_dim, AGG(total) AS revenue FROM sales_sv
GROUP BY city_dim HAVING AGG(total) > 100 ORDER BY revenue DESC LIMIT 10;
-- SELECT 支持标量表达式组合
SELECT upper(city_dim) AS city,
AGG(total) / NULLIF(AGG(order_count), 0) AS avg_order_value,
CASE WHEN AGG(total) > 1000 THEN 'high' ELSE 'normal' END AS lvl
FROM sales_sv GROUP BY city_dim;查询时需注意以下要点。
GROUP BY必须与SELECT输出的维度完全一致,不能多写,也不能漏写。维度嵌套在表达式中时,
GROUP BY仍写维度名。WHERE中不能使用指标,按聚合结果过滤请使用HAVING AGG(指标名)。
内省与YAML模型
Semantic View的定义持久化在系统表hologres.hg_semantic_view_properties中,该系统表包含schema_name、view_name、property_key和property_value四列,提供以下三类property_key。
property_key | 内容 |
| 用户提交的原始 |
| 结构化的YAML语义模型,供BI工具与AI Agent消费。 |
| 视图的owner。 |
您可以通过如下SQL列出当前Schema下的语义视图,或查看指定语义视图的YAML模型。
-- 列出当前 schema 下所有 Semantic View 及 owner
SELECT view_name, max(property_value) FILTER (WHERE property_key = 'owner') AS owner
FROM hologres.hg_semantic_view_properties
WHERE schema_name = current_schema() GROUP BY view_name;
-- 查看 YAML 语义模型
SELECT property_value AS model_yaml
FROM hologres.hg_semantic_view_properties
WHERE schema_name = current_schema()
AND view_name = 'sales_sv' AND property_key = 'model_yaml';model_yaml的结构示例如下,与DDL逐项对应,COMMENT的内容落为description字段。
name: sales_sv
description: 销售分析语义视图
tables:
- name: o
base_table: {database: mydb, schema: public, table: orders}
primary_key: {columns: [order_id]}
dimensions:
- {name: status_dim, expr: o.status}
metrics:
- {name: total, expr: sum(o.amount), description: 订单金额}
relationships:
- name: rel_oc
left_table: o
right_table: c
relationship_columns: [{left_column: customer_id, right_column: customer_id}]
relationship_type: many_to_one当前不提供YAML导入函数(hg_create_semantic_view_from_yaml()),跨环境重建语义视图请使用原始的ddl_text。
如何确认生效与排查
您可以通过以下三步确认Semantic View已生效,并排查查询结果。
确认对象存在:查询系统表
hologres.hg_semantic_view_properties,确认其中存在该view_name对应的ddl_text。查看实际执行的SQL:执行
SET hg_semantic_view_rewrite_debug = on;后再执行查询,NOTICE会输出改写后的物理SQL。多指标组场景下,可以看到多个WITH __hg_sv_xxxCTE,以及外层的LEFT JOIN ... ON NOT (q_0.dim IS DISTINCT FROM q_1.dim)(NULL-safe拼接)。校验指标未被放大:使用“先对明细去重、再聚合”的手写SQL作为基线,与语义视图的查询结果进行比对。
使用限制
SEMANTIC VIEW在建模和查询时存在以下限制。
建模限制
表达式不能跨物理alias;不支持窗口函数、子查询、参数引用、VOLATILE函数和set-returning函数。
聚合仅支持
count、sum、avg、min和max;不支持派生指标、比率指标和条件(filtered)指标,如sum(a)/count(*)。REFERENCES的目标列必须是目标表的PRIMARY KEY;不支持many-to-many关系和bridge表。暂不支持
CREATE OR REPLACE SEMANTIC VIEW和ALTER SEMANTIC VIEW,如需修改定义,请DROP后重建。
查询限制
指标必须使用
AGG()包裹;AGG()只接受裸指标名,不支持AGG(DISTINCT m)、FILTER和OVER等修饰。不支持
SELECT *、SELECT DISTINCT、窗口函数、QUALIFY和FOR UPDATE/SHARE。WHERE中不能引用指标;HAVING和ORDER BY中不能直接书写底层聚合函数,如count(*)。多表查询必须在
SELECT中至少输出一个指标,只输出维度会被拒绝;查询仅触达一张表时,按单表处理。不支持
CREATE VIEW ... AS SELECT ... FROM semantic_view,可使用CREATE TABLE AS SELECT将查询结果物化。不支持多个Semantic View之间JOIN、Semantic View与物理表JOIN,以及
WITH和集合运算等复杂外层结构。不支持DML操作:对Semantic View执行
INSERT、UPDATE、DELETE和TRUNCATE会失败,当前报错relation ... does not exist,因为语义视图未注册为普通表对象。
会被拒绝的多表形态
关系路径歧义:同一对表之间存在多条关系,或存在多条可达路径时,查询会被拒绝,报错
ambiguous relationship path。深谷陷阱(Chasm trap):同一父表下存在两条互相独立的many-side分支,查询同时使用两条分支的维度或指标时会被拒绝,报错提示需要explicit common domain。
建模建议
为每张表声明
PRIMARY KEY:这是保证多表聚合正确性(去重保护)的基础。关系方向要写对:
from_alias必须是many侧,to_alias必须是one侧;写反会让引擎误判为一对多关系,导致重复聚合。避免为同一对表定义多条关系:例如“出发机场”和“到达机场”两条
flights → airports关系,会导致查询因路径歧义被拒绝;如确需区分,建议拆分为不同的Semantic View。避免在一个查询中跨sibling分支:例如同时统计
orders与addresses两条分支的指标,当前会被拒绝,可拆分为两个查询。定义表达式时使用明确的对象名与无歧义的字面量:查询时会重新解析
ddl_text,应避免依赖会话的search_path、时区等设置。为维度和指标添加
COMMENT:COMMENT的内容会写入model_yaml的description字段,可显著提升AI Agent与NL2SQL的理解准确率。
常见错误与替代写法
查询Semantic View时的常见错误写法、对应报错与正确写法如下。
错误写法 | 报错信息 | 正确写法 |
|
|
|
|
|
|
|
|
|
|
| 显式列出维度与 |
|
|
|