Metabase 如何与您的数据库协作

Metabase 不存储您的数据。了解 Metabase 如何查询数据库中的数据,如何使用元数据来实现一些奇妙的功能,以及如何通过缓存查询和持久化模型来加速操作。

Metabase and your database

Metabase 不存储您的数据

Metabase 是一个用于查询数据库中数据并将其结果可视化的工具(Metabase 还有许多其他功能,但这并不是我们目前的重点)。它不像其他一些 BI 工具那样存储您的数据。使用 Metabase,基本设置是

  • 您将 Metabase 连接到您的数据库。
  • 您在 Metabase 中编写查询(在查询构建器或原生代码编辑器中)
  • Metabase 将 SQL 发送到数据库。
  • 您的数据库处理查询,然后将结果发送回 Metabase。
  • Metabase 将您的数据转换为漂亮的颜色(仪表板上的图表)。

Metabase 本身不会将您的数据从数据库中拉取出来进行查询处理——所有处理都在您的数据库内部进行。Metabase 所见的只是您编写的查询,以及查询返回的结果。

这里有一些细微之处,因为 Metabase 确实会对您数据库的元数据进行一些轻量级查询,以便它知道如何处理数据库返回的结果。所以,让我们来详细了解一下。

使用 Metabase 查询您的数据库

在 Metabase 中创建查询有两种方式:使用 SQL(如果您连接到 MongoDB,则使用 MongoDB 查询语言),以及使用图形化查询构建器。

原生查询

当您使用 SQL(或 MongoDB 查询语言)编写查询时,Metabase 会将该查询直接发送到您的数据库。

您在原生编辑器中编写的代码就像一个黑箱:Metabase 不会解析您的 SQL,因此它不知道您的查询中实际发生了什么,比如您正在连接哪些表、选择哪些列,或者如何筛选和聚合数据。由于查询是一个黑箱,Metabase 也无法了解结果的太多信息,因此它无法提供诸如分组、钻取或自动图表等功能。

查询构建器

查询构建器中,您可以从连接、筛选器或汇总等构建块中组装查询。

Query builder

然而,如果您使用查询构建器,Metabase 则会确切地知道您的查询中正在发生什么——涉及哪些表、列类型是什么、您执行的操作以及顺序——并且它可以使用这些信息为您提供更多功能。例如,如果 Metabase 知道您的查询中包含聚合,它可以为您提供一个选项来解除聚合结果——即钻取到单个记录;或者,如果 Metabase 看到您正在按日期列进行筛选,它可以为您提供一个日历小部件;如果它注意到您正在按分类变量进行分组,它可以自动使用这些类别构建一个条形图。

Bar chart with categories, and a calendar filter widget

查询构建器中的所有这些按钮点击都会转换为发送到您数据库的 SQL(您可以查看它生成的 SQL),但能够访问每个单独的查询元素才是 Metabase 大部分神奇之处的来源。

但现在您可能会问:如果 Metabase 不存储我的数据,它怎么会知道我有一个日期列,或者我有哪些类别呢?

Metabase 如何了解您的数据

Metabase 使用同步来了解您的数据库 schema:例如数据库中有哪些表、它们的列和类型等。从基本层面来看,同步仍然是 Metabase 发送并由您的数据库执行的查询,但它是一种特殊的查询:这些查询不返回数据本身,而是返回元数据。

Metabase 还会运行扫描来获取列中值的样本。这使得 Metabase 能够为您提供诸如筛选器中的下拉选项等功能。

Filter dropdown

值得注意的是,Metabase 只从列中获取样本,它不存储完整的列——它们保留在您的数据库中。并且它只扫描人们使用的字段(例如,仪表板上筛选器中使用的字段的值)。您也可以关闭这些同步功能。

因为 Metabase 需要在您将查询发送到数据库查询之前了解您的数据信息(这样它才能为日期列提供日历小部件),所以它需要将这些信息存储在某个地方并定期更新。这个地方就是 Metabase 的应用程序数据库

Metabase 应用程序数据库

Metabase 的应用程序数据库是一个(与您连接 Metabase 的数据库分开的)数据库,Metabase 在其中存储所有应用程序数据:用户帐户、设置、保存的问题、日志——以及有关您连接的数据库的元数据(如列及其类型)。

当您使用查询构建器构建查询时,Metabase 可以在应用程序数据库中查找有关您数据的信息,并使用这些信息为您提供筛选小部件、图表类型和钻取功能。

(如果您使用 Metabase Cloud,则无需考虑应用程序数据库——Metabase Cloud 会为您处理。但如果您是自托管,则需要单独配置一个数据库作为应用程序数据库。)

缓存查询结果

也许您的团队中有一个每个人都定期查看的仪表板,比如一个包含公司指标的仪表板。每次有人打开仪表板时,Metabase 都会将查询发送到数据库,让数据库执行它们,并检索结果。但如果结果不经常变化——例如,您可能显示每三个月才变化一次的季度指标——就没有必要每天让数据库重新计算这些数字。

您可以告诉 Metabase 将结果缓存到其应用程序数据库中(而不是您连接的数据库)。这样,当有人访问缓存的仪表板时,仪表板将加载得更快,因为您的数据库只会将预计算的结果返回给 Metabase。

Metabase 将仅缓存结果。例如,如果您的查询计算上个月销售的商品数量,Metabase 将只缓存该数字,而不是商品的详细数据。您的数据仍保留在您的数据库中。

将模型持久化回您的数据库

Metabase 具有模型——您在 Metabase 内部构建的派生数据集,以便人们更轻松地提问。要构建模型,您需要编写查询(无论是 SQL 还是使用查询构建器),然后人们就可以像使用表一样使用该模型作为数据源。

因为模型是基于查询构建的,所以每当有人根据模型提出问题时,Metabase 都需要进行一些额外的处理。例如,如果有人要求获取订单模型中的订单数量,发送到数据库的查询会比简单的SELECT COUNT(*) FROM orders更复杂,因为订单模型本身就是由一个查询定义的。

对于大型模型来说,这可能会变得昂贵且耗时,因此对于某些数据库,您可以开启模型持久化功能,Metabase 会将这些模型作为真实表存储在您的数据库中。例如,如果您持久化 Orders 模型,那么 Metabase 将在您的数据库中创建一个真实的orders表(虽然它不一定会直接命名为orders,但您懂我的意思),每当有人请求 Orders 模型中的订单数量时,您的数据库就可以直接返回该预计算的表。

后续步骤

下一步:如何在生产环境中运行 Metabase

如果您是自托管 Metabase,这里有一些基准和最佳实践。

下一篇文章
© . All rights reserved.