不写一行接口,让 DBeaver 直连你的指标层——背后只用了一个端口

先问一个扎心的问题:你们公司的"月活"到底有几种算法?

我打赌不止一种。运营那份报表按登录去重,产品那份按事件去重,财务对账时又是另一套口径。同一个词,三个数字,开会时谁也说服不了谁------最后老板拍板:"以我看到的那个为准。"

这就是没有**语义层(Semantic Layer)**的代价。指标定义散落在十个 SQL、五个报表、三个 Python 脚本里,每加一个新看板,就复制粘贴一次业务逻辑,然后祈祷没人改错 WHERE 条件。

2026 年,数据圈已经把这件事想明白了。行业里现在有一句几乎成为共识的话:"禁止让大模型和 BI 工具直接碰原始数据库,中间必须站一个语义层。" Cube、dbt Semantic Layer、AtScale 这些 Headless BI 工具,一夜之间成了 AI 时代的标配------因为无论是人还是 AI Agent,都需要一份唯一、受治理、可复用的指标定义。

道理都懂。但真到落地,大多数团队会卡在同一个地方------

痛点:语义层是好东西,可接入太重了

主流的 Headless BI 有个共同"门槛":它们大多只对外暴露 REST 或 GraphQL API。这意味着什么?

意味着你的数据分析师想用最顺手的 DBeaver 拉个数看看,不行------得先学它的 API;意味着老板的那个只会连数据库的 BI 工具,接不进来;意味着每来一个新的消费方,你都要写一层适配、维护一层接口文档。语义层本来是为了"少写点重复逻辑",结果自己变成了一个需要专门伺候的新系统。

说白了,指标是治理好了,但"取指标"这件事本身又变复杂了。

那有没有一种可能:语义层不发明新协议,而是直接假装自己是一个 Postgres 数据库?让全世界成千上万个早就支持 Postgres 的工具,零学习成本地接进来?

erupt-cube 就是这么干的。

Erupt 的方案:把 cube 变成一张会自己算数的"表"

先花一分钟说清楚 erupt-cube 是什么。它是构建在 Erupt 低代码框架之上的语义层 + 看板搭建器 :你用注解定义 OLAP cube(多维数据集),它在运行时按需生成 SQL,通过多数据源路由(ClickHouse 等)扛住十亿行级别的数据。定义指标这件事,回归到它本该有的样子------写在一个地方,用注解声明,一次定义,处处复用。

它由三个模块组成:

  • erupt-cube-semantic:核心。注解扫描、用 Velocity 模板生成 SQL、多数据源执行。
  • erupt-cube-puzzle:看板 UI。基于 DSL 的看板搭建,带发布 / 回滚版本管理和 REST API。
  • erupt-cube-sql本篇的主角------PostgreSQL 线协议端口(基于 ShardingSphere db-protocol + Netty 实现)。

重点在第三个。erupt-cube-sql 把你定义的每一个 cube,都当成一张 Postgres 表暴露出去

它到底能不能被"当成数据库"用?能,而且很像

这不是那种"勉强能连上、一查就报错"的假兼容。团队在协议层做得相当彻底:

任何 Postgres 客户端连上来,都能像逛真库一样发现你的 cube。一句 select tablename from pg_tables,就能列出所有 cube 和 explore------因为它内建了一整套 pg_catalog 模拟(pg_classpg_attributepg_typeinformation_schema 等),DBeaver 这类工具左边的对象树能正常展开,列名能自动补全,连 DBeaver 给无主键表拼的那个 ctid 系统列都被妥善处理成了 null

而真正的 SELECT 会走到 Apache Calcite 执行器(CalciteCubeSqlExecutor),带着语义层下推(pushdown)

  • 你在 WHERE 里写的维度 条件(=IN、范围、LIKE),会变成生成 SQL 里的过滤条件下推到底层;
  • 写在 WHERE 里的度量条件,会自动转成 HAVING;
  • 而对 @Parameter 的等值条件,则会直接绑定进 Velocity 模板上下文------这意味着你能把参数化的业务逻辑也塞进指标定义里。

还有一个体贴的细节:LIMIT 下推 。当你在 DBeaver 里预览数据、它悄悄拼了个 limit 501 时,这个限制会在满足条件的前提下一路下推到底层扫描------而不是把十亿行 cube 全拉出来再截断。这条对"敢不敢在生产库上点预览"至关重要。

行语义也想清楚了: select region, revenue from Sales 会按 region 聚合,一个地区一行;select * from Sales 则给你最细粒度,方便 BI 工具自己再聚合。你 SELECT 了哪些维度,就在哪个粒度上聚合------符合直觉。

安全边界:只读,且是"硬只读"

给外部工具开一个数据库端口,第一反应肯定是------会不会被写坏?

不会。这个端口是严格只读 的:所有 INSERT / UPDATE / DELETE / CREATE / DROP 都会被拒绝,返回的是和 Postgres 备库一模一样的 SQLSTATE 25006 read_only_sql_transactiontransaction_read_only 参数也如实报 on。也就是说,在客户端眼里,它就是一个"只读副本",行为完全符合 Postgres 的标准语义,工具不会懵。

上手有多快?一段配置的事

yaml 复制代码
erupt:
  cube:
    sql:
      enable: true      # 默认开启
      show-sql: true    # 默认,端口上收到的每条 SQL 都打日志,排查客户端问题的利器
      bind: 0.0.0.0     # 默认
      port: 5433        # 默认
      username: erupt
      password: secret  # 留空则为 trust 模式

然后呢?然后就没有然后了。打开 DBeaver,新建一个 PostgreSQL 数据源,端口填 5433,连上。左侧的表列表里,是你一个个 cube 的名字;每一列还带着注释,标着它是维度、度量还是参数([dimension] / [measure] / [parameter])。你的分析师用最熟悉的工具,写最普通的 SQL,查到的却是全公司口径统一、经过治理的业务指标

更妙的是 AI 这条线。前面说过,2026 年的架构共识是"别让 LLM 直接碰原始库"。而一个能说 Postgres 协议、又只读、又自带语义治理的端口,恰好就是喂给 AI Agent 的理想入口------它拿到的每个字段都有明确的业务含义注释,查出来的每个数字都是唯一口径。你不需要为 AI 再单独造一套工具。

总结一下这件事的分量

市面上大部分语义层,是"发明一套新 API,让全世界来适配我"。 erupt-cube 反过来:"我去适配全世界早就在用的 Postgres 协议。"

前者是加法------多一个系统要维护、要接入、要培训。后者是减法------你已有的每一个 BI 工具、每一个数据库客户端、每一个 psycopg 脚本,今天就能用,零学习成本。

指标定义收敛到一处,接入方式回归到最通用的协议。这大概就是语义层本该有的样子。

下一篇,我们聊聊怎么用注解在十分钟里搭出第一个能扛十亿行的 cube。

相关推荐
别动我齐刘海1 小时前
Day6 unitree_G1人形机器人GMR—— MotionInput
c语言·c++·人工智能·学习·机器学习·机器人·github
leoZ2311 小时前
实战复盘:用 Claude Code 从零搭一个 GitHub PR 统计工具
java·人工智能·python·深度学习·自然语言处理·github·llama
董员外2 小时前
RAG 系统进化论(七):Multimodal RAG(多模态 RAG),当知识存在于表格、图片和页面中
人工智能·后端·设计模式
QYR-分析2 小时前
RISC-V AI加速器SoC行业研究报告:开放架构赋能AI芯片,高增赛道开启国产化新机遇
人工智能·架构·risc-v
xiaoxiangsiyan2 小时前
LNMP + Redis Sentinel 高可用架构部署手册(续)
运维·网络·数据库·redis·缓存·架构·sentinel
用户667675093792 小时前
Java 是如何操作Redis的?从 Spring Data Redis中RedisTemplate 源码分析 ZSet 调用链
后端
NutShell Wang3 小时前
每帧重建整条路径、每秒倾倒 48MB 给 GC:实时折线图渲染架构的实测复盘
前端·性能优化·架构·图形渲染·数据可视化·vibe coding
阿里云云原生3 小时前
金融级 AI 原生架构:FinXScope 如何解决智能体从 Demo 到生产的“最后一公里”?
人工智能·金融·架构·agentscope·finxscope
凌虚3 小时前
Kubernetes 编年史:从 Borg 到云原生操作系统
后端·程序员·kubernetes