Metabase 如何与您的数据库协同工作
Metabase 不存储您的数据。了解 Metabase 如何查询您数据库中的数据,利用元数据创造奇迹,并为您提供缓存查询和持久化模型的选项以加快速度。
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 也无法了解结果的太多信息,因此无法提供像细分、钻取或自动图表等功能。
查询构建器
在查询构建器中,您可以通过连接、筛选或汇总等构建块来组合一个查询。
然而,如果您使用查询构建器,Metabase 就能确切地知道您的查询中发生了什么——涉及哪些表、列类型是什么、您执行了哪些操作以及执行顺序——并且它可以使用这些信息为您提供更多功能。例如,如果 Metabase 知道您的查询中有一个聚合,它可以为您提供一个反聚合结果的选项——即钻取到单个记录;或者,如果 Metabase 看到您正在按日期列进行筛选,它可以为您提供一个日历小部件;如果它注意到您正在按分类变量进行分组,它可以自动构建一个包含这些类别的条形图。
所有这些在查询构建器中的点击操作都会转换成发送到您数据库的 SQL(您也可以查看它生成的 SQL),但能够访问每个独立的查询元素正是 Metabase 许多神奇功能得以实现的原因。
但现在您可能会问:如果 Metabase 不存储我的数据,它又是如何知道我有一个日期列,或者我有那些类别呢?
Metabase 如何了解您的数据
Metabase 使用同步来了解您的数据库模式:比如数据库中有哪些表、它们的列和类型是什么等等。同步在基础层面上仍然是 Metabase 发送并由您的数据库执行的查询,但这是一种特殊类型的查询:这些查询返回的是元数据,而不是数据本身。
Metabase 还会运行扫描来获取列中值的样本。这使得 Metabase 能够为您提供诸如筛选器中的下拉选项等功能。
值得注意的是,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 将这些模型作为真实的表存储在您的数据库中。例如,如果您持久化了您的订单模型,那么 Metabase 将在您的数据库中创建一个实际的 orders
表(好吧,它不完全叫 orders
,但您明白这个意思),每当有人请求订单模型中的订单数量时,您的数据库就可以直接返回那个预先计算好的表。