面向数据工程师的 Metabase

数据工程师应该了解的 Metabase 相关知识。

  • Metabase 是一款基于自助分析理念的数据可视化工具。我们希望每个人都能提出关于他们自己数据的疑问。人们提出问题的难易程度取决于他们可用的数据以及您如何对这些数据进行建模。
  • Metabase 是一个独立的 Web 应用程序,它公开 REST API:您可以使用 Metabase 的 UI,或者通过我们的 REST API 与它进行交互。只需通过 HTTP 调用即可将其集成到您的堆栈的其余部分。
  • 与任何数据工具一样,请注意权限。如果您为 Metabase 分配了数据库的根账户,则任何在 Metabase 中拥有 SQL 访问权限的人都可以执行根用户可以执行的任何操作,因此请谨慎选择用于将 Metabase 连接到数据库的凭据以及授予 Metabase 组的权限。

Metabase 作为数据库的客户端

Metabase 使用 JDBC 驱动程序连接到数据库,但我们不直接使用纯驱动程序:我们将它们封装在 Clojure 代码中(Metabase 的后端是用 Clojure 编写的)。我们这样做是有原因的:我们的驱动程序是高级抽象,可将数据库数据类型转换为人们可以理解的更简单的数据类型。我们的驱动程序还会从数据库中提取元数据,以便 Metabase 能够了解如何处理您的数据。

与从原生客户端(或,如果您的数据库是 SaaS 产品,则为数据库的 Web 控制台)运行的查询相比,您不应期望在 Metabase 中运行的查询具有相同的响应时间。但我们说的是几毫秒:Metabase 需要将 JDBC 协议所说的 Java 对象转换为 JSON 所需的时间。

数据库类型和 Metabase

Metabase officially supports many databases, and some others unofficially (via community drivers). If you need to connect to a database that we don’t support, check if your database engine can do federated queries to other engines. Many database engines support connections to all kinds of services, and if these connections work, you’ll be able to use Metabase fine.

如果您没有任何方法将 Metabase 连接到数据库,您可以将数据管道化到支持的数据库中。市场上有很多产品可以让你选择源和目标,几小时后,你就可以开始使用了。

异步进程和元数据

为了方便人们查询您的数据,Metabase 会从您的数据库 同步元数据

  • 同步和扫描:Metabase 请求模式、表、列和列数据类型的列表。
  • 获取筛选值:在此过程中,Metabase 会向您的数据库发出查询,询问它找到的任何文本字段的前 1,000 个唯一值。
  • 指纹识别:此过程在前面两个之后运行。它会采样数字和日期的前 10,000 个值,以了解每个字段的最小值、最大值和平均值。这有助于 Metabase 在图表上提供更好的 x 和 y 轴,以及更多功能。

Metabase 还会提取您在 CREATE TABLE 语句中添加到表和列的注释。它会在数据参考、查询生成器和表视图中显示这些注释(将鼠标悬停在列上可查看其描述)。

您可以将同步和扫描过程从每小时更改为每天。您也可以 为特定表关闭同步和扫描

您也可以关闭获取筛选值和指纹识别,但您应该了解其影响

禁用“获取筛选值”进程

如果您的数据库有海量表,或者根本不在乎 LIMIT 子句并且执行全列扫描(例如 BigQuery),那么禁用此进程是一个不错的选择。

后果:用户在尝试在问题和仪表板中筛选文本字段时将看不到可用值的列表。他们需要输入值或在搜索框中输入。如果您将字段配置为显示搜索框,Metabase 将向数据库发出 LIKE 查询语句来查找用户输入的该值,因此如果您的数据库在此类查询方面存在问题,请采取预防措施。

如果连搜索框方法都成问题,您可能需要考虑通过外部进程获取字段值。您可以更有效地获取这些值,然后通过 API 调用填充 Metabase 仪表板中的筛选值。例如,您可以创建一个数据管道,查询您的数据库以通过优化语句(例如 HLL 或近似计数)获取列的唯一值,然后调用 Metabase 的 API 来更新仪表板中的筛选器。

禁用指纹识别

当您将鼠标悬停在列标题上时,您可能会发现数据不准确:例如最大值、最小值或平均值不正确。

如何识别 Metabase 发送到数据库的查询

同步和扫描进程

  • 查询信息模式,或您的数据库用于维护模式、表和列清单的任何模式,或者
  • 在特定表上查询 SELECT TRUESELECT 1

如果查询以 LIMIT 1000 结尾,那么您看到的是 get-filter-values 进程,而如果您看到以 LIMIT 10000 结尾的查询,那么您很可能看到的是指纹识别查询。您无法覆盖这些限制。限制决定了应用程序中如何以及显示哪些数据,例如筛选器或图表。

性能注意事项

随着数据库的增大,某些元数据查询的运行成本可能会很高。例如,如果您的数据库有 5 亿行,您可能不希望 Metabase 在随机时间运行查询来识别数据或获取字段值。我们建议在数据量显著增长时(无论是表中的行数很大还是数据库有 100 多个表)采取以下预防措施。

  • 在 **管理员设置** > **数据库** 下转到您的数据库设置。
  • 启用 **选择何时进行同步和扫描**。
  • 将同步和扫描的周期设置为每周。
  • 将 **扫描筛选值** 设置为“从不,如果需要,我会手动执行”或“添加筛选器时”。
  • 保持指纹识别禁用状态。

我们上面提到的“100 个表”的数量很大程度上取决于您的查询运行速度。如果您有 100 个包含 5 行的表,每个表有 10 列,这与 100 个包含 500 列的表,每个表有 1000 万行的情况不同,因此请谨慎对待此建议。

通知端点

Metabase 有一个专门为数据管道和/或非常大的数据库设计的特殊端点。此端点通知 Metabase 数据管道何时完成运行,以便 Metabase 可以转到特定表或模式并对其进行爬取。

如果您的数据量足够大,或者您需要在任何时候告诉 Metabase 检查特定表或模式(可能是每小时运行一次的作业不足或成本很高),请考虑使用通知端点,并将同步作业仅设置为每天运行一次。

端点有两种形式,它们都需要将 Metabase 数据库的内部 ID 传递到 URL 中

  • /api/notify/db/<id>:端点将重新扫描已知表

此端点需要在 HTTP 调用正文中传递以下参数

  • scan:‘full’ 或 ‘schema’,表示您希望 Metabase 检查所有模式或特定模式
  • table_nametable_id:您希望 Metabase 检查特定表,而不是所有表。适用于原子同步。
  • synchronous:如果您希望 Metabase 立即开始进程,或将其安排在接下来的几分钟内(当内部任务运行程序开始轮询可用作业时)。如果人们需要尽快看到更新的更改,则此选项很有用。

  • /api/notify/db/<id>/new-table:端点将搜索数据库中的新表并对其进行扫描。

此端点需要新的表名和模式名。这些参数应包含在 HTTP 调用正文中。

元数据存储

Metabase 将所有元数据存储在应用程序数据库中。如果 Metabase 找不到之前存在的模式、表或列,它将在 Metabase 的应用程序数据库中软删除该记录(它会在数据库中设置一个标志,将其完全隐藏在 UI 中)。

不要为 Metabase 分配人们永远不会查询的数据的访问权限。如果 Metabase 访问了数据库中的这些对象并对其进行了同步,它们将永远保留在那里,即使您移除了对它们的访问。这些表的存在不会给 Metabase 后端带来任何性能损失,但会使 Metabase 应用程序数据库的备份比实际需要的大。

_metabase_metadata

如果您没有在 CREATE TABLE 语句中添加任何注释,或者您的数据库不支持,您可以在数据库中创建一个具有以下结构的特殊表

CREATE TABLE public._metabase_metadata (
    keypath character varying(255) NOT NULL,
    value character varying(255)
);
INSERT INTO public._metabase_metadata VALUES
    ('table.description', 'This is a table description'),
    ('table.field.description', 'This is a field description');

您可以使用此模式为您的表和字段插入所需的元数据。

这有帮助吗?

感谢您的反馈!
订阅新闻通讯
Metabase 的更新和新闻
© . This site is unofficial and not affiliated with Metabase, Inc.