常见问题解答 (FAQ)

究竟什么是 ADBC?

从宏观层面看,ADBC 是 Arrow 原生数据库访问的标准。从微观层面看,ADBC 由两个独立但相关的部分组成:

  1. 一个用于处理数据库和 Arrow 数据的抽象 API。

  2. 一组针对该抽象 API 的具体实现,涵盖了不同语言及不同数据库的驱动程序(参见 驱动程序实现状态)。

为什么不直接使用 JDBC/ODBC?

JDBC 使用基于行的接口,例如 ResultSet。在处理类似 Arrow 数据的列式数据时,这意味着我们必须至少进行一次,有时甚至两次数据转换:

  • 第一次(可能):在驱动程序或数据库中,将列式数据转换为基于行的格式,以便通过 JDBC API 返回。

  • 第二次(总是):当客户端应用程序从 JDBC API 拉取数据时,将行转换回列。

为了秉承 Arrow “零拷贝”或“最小拷贝”的理念,我们希望避免这些不必要的转换。

ODBC 的情况类似。尽管 ODBC 确实支持 “按列绑定”,但并非所有 ODBC 驱动程序都支持它,而且使用起来更为复杂。此外,ODBC 使用由调用者分配的缓冲区(这通常意味着强制进行数据拷贝),并且 ODBC 指定的数据布局与 Arrow 并不完全兼容(无论如何都需要进行数据转换)。

因此,我们认为仅仅扩展 ODBC 不足以实现 ADBC 的目标。ODBC 在更广泛的数据库支持方面始终具有价值,并且在 ODBC 之上提供基于 Arrow 的 API 很有用。ADBC 将允许在通用库中实现/优化这种转换,为消费者提供更简单的接口,并提供一个 API,让 Arrow 原生或其他列式系统可以通过实现它来绕过这种包装器。

为什么 ODBC/Arrow 不太契合

ODBC 通过 块游标 提供对批量数据的支持,Turbodbc 展示了可以在其上构建高性能的 Arrow API。然而,它对于 Arrow 来说仍然不太契合:

  • 空值(“指示符”值)被表示为整数,需要进行转换。

  • 结果缓冲区由调用者分配。这可能导致不必要的数据拷贝。ADBC 则使用 C 数据接口(C Data Interface),从而尽可能消除拷贝(例如,如果驱动程序使用 Flight SQL)。

  • 某些数据类型的表示方式不同,需要转换。SQL_C_BINARY 可以为配合良好的驱动程序和应用程序绕过此问题,但这会导致应用程序必须对基于 Arrow 和非基于 Arrow 的数据源进行不同处理。

    • 字符串必须以 null 结尾,这需要将其拷贝到 Arrow 数组中,或者要求应用程序在数组中处理以 null 结尾的字符串。

    • 字符串是否可以包含嵌入的 null 是由实现定义的,但 Arrow 指定了 UTF-8 字符串,其中 0x00 是一个有效字节。

    • 由于缓冲区由调用者分配,驱动程序和应用程序必须配合才能处理长字符串;驱动程序必须截断该值,应用程序可以尝试再次获取该值。

    • ODBC 使用长度缓冲区而不是偏移量,需要与 Arrow 字符串数组进行另一轮转换。

    • 时间间隔使用不同的表示形式。.

ADBC 和 Arrow Flight SQL 有什么区别?

ADBC 是一项客户端 API 规范。它不定义客户端与数据库之间发生什么,仅定义作为应用程序开发者您所调用的 API。在底层,驱动程序必须接收这些 API 调用并与实际数据库进行通信。另一种视角是,ADBC 完全关注客户端,对网络协议或服务端实现不做任何规定。

Flight SQL 是一种传输协议。它指定了发送到数据库以执行各种操作(如数据库认证、创建预处理语句或执行查询)的确切命令。Flight SQL 规定了客户端和服务器必须实现的网络协议。

另一种看待方式:ADBC 驱动程序可以纯粹作为客户端库编写(例如,本仓库中的 PostgreSQL 驱动程序就是这样实现的——作为 libpq 的包装器)。但为数据库添加 Flight SQL 支持意味着要么修改数据库以运行 Flight SQL 服务,要么将数据库置于翻译 Flight SQL 与数据库协议的代理之后。

为什么不直接使用 Arrow Flight SQL?

由于 ADBC 是客户端的,它支持那些不支持返回 Arrow 数据,或通过 Flight SQL 以外的协议支持 Arrow 数据的数据库。

那么我们还需要 Arrow Flight SQL 吗?

Flight SQL 是一个具体的协议,数据库厂商可以直接实现它,而无需设计自己的协议。此外,Flight SQL 还有 JDBC 和 ODBC 驱动程序,以实现最大程度的兼容性。

类比一下:许多数据库实现了 PostgreSQL 传输协议,以便能够访问所有 PostgreSQL 客户端,包括 JDBC 和 ODBC 驱动程序。(JDBC/ODBC 用户仍然可以使用其他驱动程序来处理其他数据库。)

对于 Arrow 生态系统,我们希望数据库能实现 Flight SQL 传输协议,从而让它们能够访问所有的 Flight SQL 客户端,包括 ADBC、JDBC 和 ODBC 驱动程序。(ADBC 用户仍然可以使用其他驱动程序来处理其他数据库。)

那么“ADBC Flight SQL 驱动程序”是什么?

ADBC Flight SQL 驱动程序使用 Flight SQL 传输协议(数据库服务器暴露该协议)实现了 ADBC API 标准(应用程序与此交互)。因此,它是一个通用的驱动程序,只要数据库实现了 Flight SQL,它就可以与许多数据库对话。

这有点不同寻常,因为您找到的大多数数据库驱动程序和协议都是针对特定数据库的。但 Flight SQL 和 ADBC 从一开始就被设计为与具体数据库无关。

听起来它们有重叠,但它们在不同的抽象层面上互补。数据库开发者只需提供一个 Flight SQL 服务,就能免费获得 ADBC、JDBC 和 ODBC 驱动程序,而无需自行构建和维护这些驱动程序。数据库用户只需使用 ADBC 这一种 Arrow 原生 API,即可同时处理 Arrow 原生和非 Arrow 原生的数据库,无论这些数据库支持 Flight SQL、自定义 Arrow 原生协议,还是根本不支持 Arrow 原生协议。

那么“ADBC JDBC 驱动程序”又是什么?

ADBC JDBC 驱动程序(或假设的 ADBC ODBC 驱动程序)将 JDBC API 适配到 ADBC API,以便 ADBC 用户能够与提供 JDBC API 的数据库进行交互。虽然这无法提供最佳性能(您需要付出数据来回转换的代价!),但它免去了您自己编写这些转换代码的麻烦。

类似的库已经存在;例如,Turbodbc 将任何 ODBC 驱动程序包装在 Python 的 DBAPI (PEP 249) 中,而 arrow-jdbc 将任何 JDBC 驱动程序包装在一个定制的 Arrow API 中。

所有这些 API 是如何结合在一起的?

_images/AdbcQuadrants.mmd.svg

我们可以根据两个轴来划分 API:Arrow 原生 vs 基于行,以及特定于数据库 vs 与数据库无关。

与数据库无关的 API 从供应商中抽象出来,包括 ADBC、JDBC、ODBC 以及某种程度上的 Flight SQL。(如上所述,Flight SQL 仍然需要特定的供应商支持;而 xDBC 则不需要。)

特定于数据库的 API 是供应商为其系统制作的,尽管其他系统最终可能会为了兼容性而重新实现这些 API(正如 PostgreSQL 传输协议常做的那样)。

像 ADBC、Flight SQL 和 BigQuery Storage API 这样的 Arrow 原生 API 原生地返回 Arrow 数据,或者更广泛地说是列式数据。对于处理大量数据的应用程序,这可以提供性能优势。

像 JDBC、ODBC 和 PostgreSQL 传输协议这样的基于行的 API 一次处理一行数据。这对某些类型的应用程序可能更方便。

什么是 ADBC 驱动程序管理器?

驱动程序管理器(在 C/C++ 中)是一个库,它实现了驱动程序 API,但在后台动态加载和管理多个驱动程序。它允许应用程序链接到一个库,但同时使用多个驱动程序。这避免了多个驱动程序在提供相同的名称下提供相同的 ADBC API 时可能产生的符号冲突。

欲了解详细信息,请参见 驱动程序与驱动程序管理器如何协同工作

什么是 ADBC SQL 方言?

这是个陷阱问题!ADBC 不是一种 SQL 方言。ADBC 驱动程序所要做的就是将您的查询字符串传递给数据库,并将结果集作为 Arrow 数据获取。在这方面,它类似于 JDBC。(ODBC 定义了一种“标准”SQL 方言;而 ADBC 没有这样做。)

对于尝试解决定义独立于供应商的查询语言这一问题的项目,请参阅 Substrait

下一次发布是什么时候?

没有固定的发布周期。我们目前的目标是每 6-8 周发布一次。

一旦发布被标记,项目会给 Arrow PMC 至少 72 小时的时间对版本进行投票。投票结束后,包会被上传到 PyPI、conda-forge 等地方。因此,即使在发布之后,二进制包的可用也可能需要一些时间。

1.0 版本什么时候/在哪里?这个项目准备好了吗?

项目的不同部分有不同的版本号。我们认为某些实现(如 Go)已经达到“1.0”就绪水平,而其他实现(如 Java)仍处于 1.0 之前。驱动程序实现状态 对各个驱动程序实现的状况有一个大致的概述。

我在哪里可以了解更多关于 ADBC 的基本原理?

请参阅 相关工作