ADBC 簡介:適用於 Apache Arrow 的資料庫存取
已發布 2023年1月5日
作者 Apache Arrow PMC (pmc)
Arrow 社群很高興推出 Arrow 資料庫連線能力 (ADBC) 規格的 1.0.0 版本。ADBC 是 JDBC/ODBC 的柱狀式、低額外負荷替代方案,適用於分析應用程式。換句話說:ADBC 是一個單一 API,用於將 Arrow 資料輸入和輸出不同的資料庫。
動機
應用程式通常使用 API 標準,例如 JDBC 和 ODBC 來與資料庫互動。這樣一來,無論底層資料庫為何,它們都可以針對相同的 API 進行編碼,從而節省開發時間。粗略來說,當應用程式使用這些 API 執行查詢時
- 應用程式透過 JDBC/ODBC API 提交 SQL 查詢。
- 查詢傳遞到驅動程式。
- 驅動程式將查詢轉換為資料庫特定的協定,並將其傳送至資料庫。
- 資料庫執行查詢,並以資料庫特定的格式傳回結果集。
- 驅動程式將結果轉換為 JDBC/ODBC API 所需的格式。
- 應用程式使用 JDBC/ODBC API 迭代結果列。
然而,當柱狀資料發揮作用時,問題就產生了。JDBC 是面向列的 API,雖然 ODBC 可以支援柱狀資料,但其類型系統和資料表示法與 Arrow 並不完全匹配。因此,通常柱狀資料必須在步驟 5 中轉換為列,在沒有執行「有用」工作的情況下耗費資源。
這種不匹配對於柱狀資料庫系統來說是有問題的,例如 ClickHouse、Dremio、DuckDB 和 Google BigQuery。在用戶端方面,諸如 Apache Spark 和 pandas 之類的工具最好直接取得柱狀資料,跳過該轉換。否則,它們會犧牲效能。同時,這種轉換並非總是可避免的。像 PostgreSQL 這樣的面向列的資料庫系統不會消失,這些用戶端仍然會想要從它們那裡取用資料。
開發人員有幾個選項
- 僅使用 JDBC/ODBC。這些標準將繼續存在,資料庫支援想要使用它們的應用程式是有道理的。但是,當資料庫和應用程式都是柱狀時,這意味著為了 JDBC/ODBC 而將資料轉換為列,只是為了讓用戶端將它們轉換回柱狀!效能會受到影響,開發人員必須花時間實作轉換。
- 使用 JDBC/ODBC 到 Arrow 的轉換函式庫。諸如 Turbodbc 和 arrow-jdbc 之類的函式庫處理用戶端的列到柱狀轉換。但這並未從根本上解決問題。仍然需要不必要的資料轉換。
- 使用廠商特定的協定。對於某些資料庫,應用程式可以使用資料庫特定的協定或 SDK 來直接取得 Arrow 資料。例如,應用程式可以透過 Arrow Flight SQL 使用 Dremio。但是,想要支援多個資料庫廠商的用戶端應用程式將需要與它們每個都整合。(看看 Trino 實作的所有 連接器。)而且像 PostgreSQL 這樣的資料庫一開始就沒有提供支援 Arrow 的選項。
目前的情況是,用戶端必須在繁瑣的整合工作或犧牲效能之間做出選擇。我們可以做得更好。
ADBC 簡介
ADBC 是一個基於 Arrow、廠商中立的 API,用於與資料庫互動。使用 ADBC 的應用程式只需接收 Arrow 資料。它們不必自己進行任何轉換,也不必整合每個資料庫的特定 SDK。
就像 JDBC/ODBC 一樣,在 ADBC API 底下是驅動程式,它們為特定的資料庫轉換 API。
- 適用於 Arrow 原生資料庫的驅動程式只需傳遞 Arrow 資料,無需轉換。
- 適用於非 Arrow 原生資料庫的驅動程式必須將資料轉換為 Arrow。這免除了應用程式執行此操作,並且驅動程式可以針對其資料庫最佳化轉換。
- 應用程式透過 ADBC API 提交 SQL 查詢。
- 查詢傳遞到 ADBC 驅動程式。
- 驅動程式將查詢轉換為資料庫特定的協定,並將查詢傳送至資料庫。
- 資料庫執行查詢,並以資料庫特定的格式傳回結果集,理想情況下是 Arrow 資料。
- 如果需要:驅動程式將結果轉換為 Arrow 資料。
- 應用程式迭代 Arrow 資料批次。
應用程式僅處理一個 API,並且僅使用 Arrow 資料。
ADBC API 和驅動程式實作正在開發中。例如,在 Python 中,ADBC 套件提供了一個熟悉的 DBAPI 2.0 (PEP 249) 風格介面,並擴展了取得 Arrow 資料的功能。我們可以輕鬆地從 PostgreSQL 中取得 Arrow 資料
import adbc_driver_postgresql.dbapi
uri = "postgresql://#:5432/postgres?user=postgres&password=password"
with adbc_driver_postgresql.dbapi.connect(uri) as conn:
with conn.cursor() as cur:
cur.execute("SELECT * FROM customer")
table = cur.fetch_arrow_table()
# Process the results
或 SQLite
import adbc_driver_sqlite.dbapi
uri = "file:mydb.sqlite"
with adbc_driver_sqlite.dbapi.connect(uri) as conn:
with conn.cursor() as cur:
cur.execute("SELECT * FROM customer")
table = cur.fetch_arrow_table()
# Process the results
注意:實作仍在開發中。請參閱文件以取得最新的範例。
那 {Flight SQL, JDBC, ODBC, …} 呢?
ADBC 填補了相關專案未解決的特定利基市場。它既是
- Arrow 原生:由於 C Data Interface,ADBC 可以無額外負荷地傳遞 Arrow 資料。如前所述,JDBC 是面向列的,而 ODBC 在實作方面存在注意事項,這使得它難以與 Arrow 一起使用。
- 廠商中立:ADBC 驅動程式可以使用任何底層協定實作 API,而 Flight SQL 需要伺服器端支援,這可能不容易新增。
廠商中立 (資料庫 API) | 廠商特定 (資料庫協定) | |
---|---|---|
Arrow 原生 | ADBC | Arrow Flight SQL BigQuery Storage gRPC 協定 |
面向列 | JDBC ODBC (通常面向列) |
PostgreSQL 線路協定 表格資料串流 (Microsoft SQL Server) |
ADBC 並不打算全面取代 JDBC 或 ODBC。但是對於只需要大量柱狀資料存取的應用程式,ADBC 可以讓它們避免資料轉換的額外負荷和繁瑣的整合工作。
同樣地,在 Arrow 專案中,ADBC 並不取代 Flight SQL,而是補充它。ADBC 是一個 API,讓用戶端可以輕鬆地與不同的資料庫協作。同時,Flight SQL 是一個 線路協定,資料庫伺服器可以實作它,以同時支援 ADBC、JDBC 和 ODBC 使用者。
參與其中
ADBC 作為 Arrow 生態系統的一部分,旨在全面涵蓋資料庫互動的各個方面
- Arrow 提供通用的柱狀資料格式,
- Arrow Flight SQL 為資料庫伺服器提供通用的線路協定,
- 而 ADBC 為資料庫用戶端提供通用的 API。
若要開始使用 ADBC,請參閱文件以取得建置指示和簡短教學課程。(套件的正式發行仍在進行中。)如果您有興趣了解更多或做出貢獻,請透過郵件列表或 GitHub Issues 與我們聯繫。
ADBC 的實現離不開多位 Arrow 社群成員和專案的協助和參與。特別是,我們要感謝 DuckDB 專案和 R DBI 專案的成員,他們根據標準的早期修訂版建構了原型,並針對設計提供了回饋。而且 ADBC 建立在現有的 Arrow 專案之上,包括 Arrow C Data Interface 和 nanoarrow。
感謝 Fernanda Foertter 協助製作部分圖表。