Malloy会取代SQL语言吗?- Carlin


SQL的基础是在关系型数据库的黎明时期奠定的。那时,还没有数据仓库,没有商业智能工具,当然也没有分析工程师这样的东西。然而,SQL仍然是大多数数据专业人员与他们的原始材料进行交互的主要用户界面。底层技术已经有了不可估量的改进,但除了对ANSI标准的少量更新外,语言的核心仍然没有改变。在无数数据专业人员使用了40多年之后,我们与数据的接口实际上是一样的,这几乎是一个奇迹。

自从SQL诞生以来,许多计算机科学家和数据库研究人员已经表达了他们对SQL的鄙视,他们的批评通常是有根据的;然而,每一次试图取代它作为事实上的标准的认真尝试都失败了。大多数试图取代SQL的尝试主要是为了解决该语言尴尬的语法问题;例如,将FROM子句放在前面,或者取消对HAVING和QUALIFY子句的需要。不幸的是,现实情况是,SQL对于大多数使用情况来说是 "足够好的",而且根据艾肯法则,程序员培训是编程语言的主要成本。看来,语法糖根本不足以克服SQL的顽固性。

这让我想到了Malloy,一种新的数据分析查询语言,目前由Looker的创始人和前CTO Lloyd Tabb开发。Malloy解决了许多困扰SQL的美学问题,但在我看来,更有趣的是它将查询语言和语义层整合为一种单一的语言。

什么是语义层,为什么它很重要?

语义层
语义层的目的是在数据库表之上编纂特定领域的逻辑,并防止用户发出语法上有效、但语义上无意义的查询。
例如,如果你在两个键不正确的表之间写一个连接,会发生什么?
在大多数关系型数据库中,主键和外键只是字符串或数字。一些数据库可能会强制执行参考完整性,但是如果你试图将CUSTOMER_ID和ORDER_ID连接起来,大多数数据库不会抱怨。

再比如,通常情况下,主键列是整数,数据库会很乐意让你把它们作为任何需要数字输入的聚合函数的输入,比如SUM或AVG,即使结果是无意义的。

最后,每个组织都有必须应用于其数据集的特殊规则,以便正确计算关键指标。
例如,在计算投资者关系部向华尔街报告的收入时,需要哪些输入和调整?那些只能接触到原始数据,而不具备必要的特定领域知识的人,将无法准确地再现这些指标。

语义层提供了一个设置这些规则并要求查询遵守这些规则的地方;例如,哪些连接是有效的,哪些列可以被分组,或者哪些输入可以进入特定的聚合函数。

语义层通常采取的形式是位于数据库之上的应用程序,以及定义上述规则的配置文件。
目前市场上的产品例子包括SAP的Business Objects Universe,Looker的LookML和Cube。

我是Looker的早期用户,那次经历给我留下了深刻的印象。LookML允许我定义必要的逻辑,将我们所有的数据源打包成一个有凝聚力的单一真相源。
我们的数据仓库从一个只有熟练的数据科学家才能操作的乱七八糟的表格,变成了一个值得信赖的存储库,一般的项目管理人员或业务伙伴都可以从中获取洞察力。

尽管我们从Looker和LookML中获得了巨大的价值,但分析和数据科学小组从来没有像我这样喜欢它。
与Tableau相比,Looker的交互式数据探索和分析能力相对有限,而大多数数据科学家将探索和分析视为他们的主要活动。
他们认为编写LookML配置是件苦差事,而用户体验也没有帮助。

要添加一个新的维度或措施,数据科学家必须编辑YAML配置文件,将他们的变化检查到源控制中,并在他们查看任何结果之前重新加载他们的配置。
一个简单的工作流程,在Tableau中可能需要2秒,在Looker中可能需要1分钟以上。

当试图探索一个数据集时,"以思考的速度 "进行迭代的能力是至关重要的,而这种额外的延迟是许多人感到沮丧的根源。
因此,数据建模和数据探索被认为是两个完全独立的学科。
数据科学家们非常喜欢帮助后者的工具,这对所有不是数据科学家的人来说是非常不利的。

Malloy
Malloy 是一种可以编译为 SQL 的查询语言,任何使用过 SQL 的人都非常熟悉。该团队还构建了一个 VSCode 扩展,允许用户连接到数据库并开始编写查询,目前支持 BigQuery、DuckDB 和 Postgres。Malloy 中的语义层是通过编写 Sources 来访问的。

让我们看一下来自Malloy Github repo的示例 Source ,查看航班数据库:


source: flights is table('duckdb:data/flights.parquet') + {
  primary_key: id2

  // rename some fields as from their physical names
  rename: origin_code is origin
  rename: destination_code is destination

 
// join all the data sources
  join_one: carriers with carrier
  join_one: origin is airports with origin_code
  join_one: destination is airports with destination_code
  join_one: aircraft with tail_num

 
// declare some resusable aggregate calculations
  measure:
    flight_count is count()
    total_distance is sum(distance)
  }
}

source源可以被认为是一个表以及与该表相关的计算和关系的集合。这些计算可以包括度量(聚合函数)、维度(标量计算)和查询定义;连接是源之间的关系。

此 Source 有几个关键组件:数据库中表的名称、表的主键、可以连接哪些表以及通过哪些列以及哪些聚合(也称为度量)是有效的。在 VSCode 扩展中,我可以使用这个源作为数据探索或分析的起点,只需编写一个引用它的查询,然后点击“运行”CodeLens 按钮:

VSCode 扩展将 Malloy 查询编译为 SQL,针对数据库发出它,并将结果呈现在另一个窗口中。

这种探索可能会刺激我以某种方式更新源码,我可以在IDE中直接进行更新,并立即重新执行查询。这种读取-评估-打印的循环实现了快速迭代,而LookML或者其他任何需要SQL和YAML进行配置的语义层(甚至更糟糕的是,往往还需要一个单独的API来实际查询数据)是根本不可能的。Malloy的语义层结合了两个独立但又错综复杂的学科--探索数据和围绕数据编纂规则。这不仅消除了这两个任务之间的上下文切换的开销,而且实际上还改善了每个任务的个人体验。实现一个数据模型可以积极地改善数据探索的体验,反之亦然。

虽然语义层对我来说是主要的吸引力,但还有许多其他值得注意的功能。一个特别好的功能是它对嵌套数据的处理。用SQL编写带有嵌套小计的滚动查询可能会很痛苦,而且大多数SQL方言中的GROUP BY ROLLUP函数会产生非常难以处理的尴尬输出。

Malloy 的内容比我在这里分享的要多得多,因此我鼓励您查看Github 存储库文档

概括
Malloy 最终会成为取代 SQL 的语言吗?这是一项几乎不可能完成的任务,但我非常希望它能够成功。与其他只寻求改进语言美感的项目不同,Malloy 采取了更加雄心勃勃的方法,并解决了堆栈中关键缺失的部分。它的查询语言和语义层的结合有可能从根本上改变分析和商业智能的学科,使其变得更好。其他趋势,例如 BigQuery 和 Snowflake 等少数数据平台产品的崛起和主导地位,意味着 Malloy 要真正成功,它必须支持的数据库目标相对较少。该项目还处于早期阶段,谁知道它会从这里走向何方,