常见问题 (FAQ)¶
ADBC 究竟是什么?¶
从宏观层面看,ADBC 是用于 Arrow 原生访问数据库的标准。从微观层面看,ADBC 是两个独立但相关的事物:
一个用于处理数据库和 Arrow 数据的抽象 API。
该抽象 API 在不同语言中的一组具体实现,以及针对不同数据库的驱动程序(参见驱动程序实现状态)。
为什么不直接使用 JDBC/ODBC?¶
JDBC 使用基于行的接口,例如 ResultSet。当处理列式数据(如 Arrow 数据)时,这意味着我们必须进行至少一次,甚至可能是两次数据转换:
一次(可能)在驱动程序或数据库中,将列式数据转换为基于行的格式,以便通过 JDBC API 返回。
一次(总是)当客户端应用程序从 JDBC API 拉取数据时,将行转换为列。
为了秉持 Arrow 的“零拷贝”或“最小拷贝”理念,我们希望避免这些不必要的转换。
ODBC 的情况类似。尽管 ODBC 支持“列式绑定”,但并非所有 ODBC 驱动程序都支持,并且使用起来更复杂。此外,ODBC 使用调用者分配的缓冲区(这通常意味着强制数据复制),并且 ODBC 指定的数据布局与 Arrow 不完全兼容(无论如何都需要数据转换)。
因此,我们认为仅仅扩展 ODBC 不足以实现 ADBC 的目标。ODBC 将始终对更广泛的数据库支持具有价值,并且在 ODBC 之上提供基于 Arrow 的 API 是有用的。ADBC 将允许在通用库中实现/优化这种转换,为消费者提供更简单的接口,并提供一个 Arrow 原生或其他列式系统可以实现的 API 来绕过此包装器。
为什么 ODBC/Arrow 不完全匹配
ODBC 通过块游标提供批量数据支持,Turbodbc 证明可以在其之上构建高性能的基于 Arrow 的 API。然而,它与 Arrow 仍然不太契合:
空值(“指示符”值)以整数表示,需要转换。
结果缓冲区由调用者分配。这可能导致不必要的数据复制。ADBC 转而使用 C 数据接口,在可能的情况下(例如,如果驱动程序使用 Flight SQL)消除复制。
某些数据类型表示方式不同,需要转换。SQL_C_BINARY 可以为协同工作的驱动程序和应用程序规避此问题,但随后应用程序将不得不以不同方式处理基于 Arrow 和非基于 Arrow 的数据源。
字符串必须以空字符终止,这需要复制到 Arrow 数组中,或者要求应用程序在数组中处理以空字符终止的字符串。
字符串是否可以嵌入空字符是实现定义的,但 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 是客户端,所以 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 如何协同工作?¶
我们可以根据两个轴线划分 API:Arrow 原生与面向行,以及数据库特定与数据库无关。
数据库无关的 API 从供应商中抽象出来,包括 ADBC、JDBC、ODBC,以及在某种程度上 Flight SQL。(Flight SQL,如上所述,仍然需要特定的供应商支持;xDBT 则不需要。)
数据库特定的 API 由供应商为其系统制作,尽管其他系统最终可能会重新实现这些 API 以实现兼容性(就像 PostgreSQL 网络协议经常做的那样)。
Arrow 原生 API,如 ADBC、Flight SQL 和 BigQuery Storage API,原生返回 Arrow 数据,或者更一般地返回列式数据。这可以为处理大量数据的应用程序提供性能优势。
面向行的 API,如 JDBC、ODBC 和 PostgreSQL 网络协议,一次处理一行。这对于某些类型的应用程序可能更方便。
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 的原理?¶
请参阅相关工作。