DuckDB 作為一款新興的嵌入式分析型資料函式庫,提供了一種在本地高效處理和查詢大量資料的解決方案。不同於傳統的大資料系統,DuckDB 以其單節點、記憶體內運算的特性,簡化了資料分析流程,降低了使用門檻。它支援多種資料格式,如 CSV、JSON、Parquet 等,並能直接存取雲端儲存,減少資料傳輸成本。其向量化查詢引擎和欄位導向架構,能充分利用現代 CPU 架構,大幅提升查詢效率。DuckDB 也提供豐富的 SQL 功能和擴充,方便資料轉換、過濾和分析。
深入探索DuckDB:新一代資料分析工具
DuckDB是一種現代化的嵌入式分析資料函式庫,能夠在本地高效處理和查詢來自不同來源的龐大資料。不同於傳統的大資料系統,DuckDB以其單節點記憶體資料函式庫的設計,為資料分析帶來了革命性的變革。
1.1 什麼是DuckDB?
DuckDB由Mark Raasveldt和Hannes Mühleisen於2018年建立,最初是作為荷蘭國家數學和電腦科學研究中心(CWI)的研究專案。隨後,DuckDB Labs成立,以進一步推動DuckDB的發展。DuckDB基金會則負責維護該專案的智慧財產權,並確保其在MIT許可證下的持續開源發展。
1.2 為什麼選擇DuckDB?
DuckDB讓資料分析變得更快、更有趣,無需設定龐大的Apache Spark叢集或執行雲資料倉儲來處理幾百GB的資料。它可以直接存取多種資料來源,並在資料所在的位置進行處理,避免了資料傳輸的成本和複雜性,從而節省時間、金錢並減少挫折感。
使用範例:處理AWS存取日誌
例如,處理儲存在S3上的AWS存取日誌檔案時,使用DuckDB佈署在EC2虛擬機器上,可以直接查詢和分析這些資料,而無需透過AWS Athena等雲端服務,既降低了成本,又提高了效率。
DuckDB的核心架構與優勢
DuckDB的架構設計使其能夠高效處理和分析大規模資料。它採用向量化查詢引擎,能夠平行處理資料塊,充分利用現代多核CPU架構的優勢。此外,DuckDB支援多種擴充套件和使用者自定義函式,以及多種使用者介面,包括CLI、API和與其他系統的低階整合。
查詢處理流程
下圖展示了DuckDB的查詢處理流程: 此圖示展示了DuckDB如何將SQL陳述式轉換為可執行的物理計劃,並透過最佳化器提升查詢效率。
#### 內容解密:
- SQL Statement:使用者輸入的SQL查詢陳述式。
- Parser:語法解析器,負責將SQL陳述式解析成抽象語法樹(AST)。
- Unoptimized logical plan:未經最佳化的邏輯計劃,代表了查詢的初步執行計劃。
- Optimizer:最佳化器,透過各種最佳化策略提升查詢效率。
- Optimized logical plan:經過最佳化的邏輯計劃,更高效地表示查詢執行過程。
- Physical planner:物理計劃生成器,將邏輯計劃轉換為具體的物理執行計劃。
- Physical plan:物理計劃,直接指導查詢的執行。
- Query Runtime:查詢執行時,負責執行物理計劃並傳回結果。
DuckDB的應用場景與優勢
- 高效資料分析:能夠快速處理和分析大規模資料,無需複雜的大資料基礎設施。
- 多源資料支援:支援多種資料格式和來源,包括CSV、JSON、Parquet等,以及與多種資料函式庫的整合。
- 靈活佈署:可在本地、雲端或邊緣環境中佈署,滿足不同場景的需求。
綜上所述,DuckDB作為新一代的嵌入式分析資料函式庫,以其高效、靈活和易用的特點,為資料分析領域帶來了新的可能性。無論是在本地還是雲端,DuckDB都能提供強大的資料處理能力,幫助使用者更快速、更經濟地完成資料分析任務。
DuckDB簡介及其優勢
DuckDB是一種針對分析工作負載進行最佳化設計的資料函式庫系統,能夠在本地環境中高效處理結構化資料。相較於傳統的資料分析工具,DuckDB提供了一個更快速、更簡便的資料處理與分析方案。
DuckDB的主要特點
DuckDB支援ANSI SQL標準,並在其基礎上進行了擴充套件,提供了諸如SELECT * EXCLUDE()、SELECT * REPLACE()、GROUP BY ALL等創新功能。此外,DuckDB還具備處理複雜巢狀資料的能力,透過其STRUCT資料型別及相關函式,能夠簡化複雜資料的操作。
使用DuckDB的時機
當你的資料分析任務可以透過SQL表達,並且資料已經準備就緒(非串流資料),且資料量不超過數百GB時,DuckDB是一個理想的選擇。它的欄位導向(columnar)引擎能夠有效處理寬表(多欄位)和大表(多列)。此外,DuckDB能夠處理多種資料格式,並可擴充套件以整合其他系統。
適用的分析任務
DuckDB適用於多種資料分析任務,例如:
- 分析日誌檔案,無需將其複製到新的位置
- 量化個人醫療資料,如運動員監測心率
- 報告智慧電表中的電力生產和消耗資料
- 最佳化現代運輸作業中的騎行和駕駛資料
- 為機器學習訓練預處理和清理使用者生成的資料
DuckDB的優勢
相較於其他工具,DuckDB具有多項優勢:
- 比SQLite更快,特別是在分析工作負載方面
- 比Spark叢集更容易設定
- 比pandas具有更低的資源需求
- 不會像Polars那樣拋出奇怪的Rust錯誤
- 比PostgreSQL、Redshift等關係型資料函式庫更容易設定和使用
- 比Talend更快、更強大的資料轉換能力
何時不應使用DuckDB?
儘管DuckDB具有多項優勢,但它並不適合所有情況。由於它是一個分析型資料函式庫,因此對交易和平行寫入存取的支援有限。因此,它不適合處理和儲存任意到達的輸入資料的應用程式和API。
此外,DuckDB的處理能力受限於電腦的主記憶體大小。雖然它支援溢位到磁碟(out-of-memory processing),但這主要是針對例外情況設計的。因此,在大多數情況下,處理的資料量限制在幾百GB以內。
DuckDB的使用案例
DuckDB在多種場景中非常有用,尤其是在需要高效處理現有資料的情況下,例如直接存取pandas或Polars DataFrames中的資料,而無需複製資料。同樣,由DuckDB生成的輸出和表格可以直接用作DataFrames,而無需額外的記憶體使用或傳輸。
使用DuckDB進行高效資料處理與分析
1.6 DuckDB的適用場景
本文假設讀者已經擁有想要分析或轉換的資料。這些資料可以儲存在CSV、Parquet或JSON等平面檔案中,也可以位於PostgreSQL或SQLite等其他資料函式庫系統中。為了便於讀者學習,本文在GitHub倉函式庫中提供了示例資料:https://github.com/duckdb-in-action/examples。
根據不同的使用場景,讀者可以暫時使用DuckDB來轉換、過濾資料,並將其傳遞給其他格式(圖1.3)。在大多數情況下,讀者會建立表格來持久化資料,以便進行後續的高效能分析。在此過程中,讀者還可以轉換和糾正列名、資料型別和值。如果輸入資料是巢狀檔案,DuckDB可以將其展開和平展,以便進行更高效的關係資料分析。
圖1.3 在資料管道中使用DuckDB
資料處理流程的步驟
在下一步中,讀者需要確定哪些SQL功能或DuckDB特性可以幫助完成資料分析或轉換。讀者還可以進行探索性資料分析(EDA),快速瞭解資料的分佈、範圍和關係。
在瞭解資料之後,讀者可以開始實際的分析任務。這裡,讀者將逐步構建相關的SQL陳述式,並在每個步驟中驗證結果樣本是否符合預期。在此階段,讀者可能會建立額外的表格或檢視,然後使用高階SQL功能,如視窗函式、公共表表達式和透視表。最後,讀者需要決定結果的輸出方式:將其轉換為檔案或資料函式庫,透過應用程式或API提供給使用者,或在Jupyter筆記本或儀錶板中進行視覺化。
1.7 資料處理流程
1.7.1 資料格式和來源
DuckDB支援多種資料格式和來源,並允許讀者以簡單的方式檢查和分析這些資料。與其他資料系統(如SQL Server)不同,DuckDB不需要事先指定schema細節。在讀取資料時,資料函式庫使用合理的預設值和資料中的固有schema資訊,讀者可以在需要時覆寫這些資訊。
DuckDB支援多種資料格式:
- CSV檔案可以批次平行載入,其列會自動對映。
- DataFrames的記憶體可以在同一個Python程式中直接由DuckDB處理,無需複製資料。
- JSON格式可以被解構、平展並轉換為關係表格。DuckDB還具有用於儲存此類別資料的JSON型別。
- 可以查詢Parquet檔案及其schema後設資料。查詢中使用的謂詞會被下推到Parquet儲存層進行評估,以減少載入的資料量。這是讀寫資料湖的理想列式格式。
- 可以透過Arrow Database Connectivity(ADBC)讀取Apache Arrow列式資料,無需複製和轉換資料。
- 存取雲端儲存桶(如S3或GCP)中的資料,可以減少傳輸和複製基礎設施,並允許廉價處理大量資料。
1.7.2 資料結構
DuckDB處理多種表格、檢視和資料型別。對於表格列、處理和結果,有比傳統資料型別(如字串、數值、日期、時間戳、間隔、布林值和二進位制大物件)更多的資料型別可用。
DuckDB還支援結構化資料型別,如列舉、列表、對映(字典)和結構體:
- 列舉——索引的、命名的元素集合,可以高效地儲存和處理。
- 列表或陣列——儲存多個相同型別的元素,並有多種函式可供操作。
- 對映——高效的鍵值對,可用於儲存鍵控的資料點。它們在JSON處理過程中被使用,可以透過多種方式構建和存取。
- 結構體——一致的鍵值結構,其中相同的鍵始終具有相同資料型別的值。這允許更高效地儲存、推理和處理結構體。
使用Plantuml圖表示資料處理流程
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title DuckDB高效資料分析工具
package "資料庫架構" {
package "應用層" {
component [連線池] as pool
component [ORM 框架] as orm
}
package "資料庫引擎" {
component [查詢解析器] as parser
component [優化器] as optimizer
component [執行引擎] as executor
}
package "儲存層" {
database [主資料庫] as master
database [讀取副本] as replica
database [快取層] as cache
}
}
pool --> orm : 管理連線
orm --> parser : SQL 查詢
parser --> optimizer : 解析樹
optimizer --> executor : 執行計畫
executor --> master : 寫入操作
executor --> replica : 讀取操作
cache --> executor : 快取命中
master --> replica : 資料同步
note right of cache
Redis/Memcached
減少資料庫負載
end note
@enduml
此圖示展示了使用DuckDB進行資料處理的基本流程,從載入資料到使用分析結果的全過程。
1.7.3 編寫SQL
在分析資料時,通常首先要了解資料的形狀。然後,從簡單的查詢開始,逐步構建更複雜的查詢。可以使用DESCRIBE來瞭解列和資料的分佈情況。
SQL查詢範例
-- 查看錶格結構
DESCRIBE my_table;
-- 簡單查詢
SELECT * FROM my_table LIMIT 10;
-- 使用WHERE子句過濾資料
SELECT * FROM my_table WHERE column_name = 'value';
-- 使用聚合函式分析資料
SELECT column_name, COUNT(*)
FROM my_table
GROUP BY column_name;
內容解密:
DESCRIBE my_table;:用於檢視my_table表格的結構,包括列名、資料型別等資訊。SELECT * FROM my_table LIMIT 10;:從my_table中選取前10行資料,用於快速預覽資料內容。SELECT * FROM my_table WHERE column_name = 'value';:根據條件column_name = 'value'過濾資料,選取符合條件的行。SELECT column_name, COUNT(*) FROM my_table GROUP BY column_name;:按column_name分組,並計算每組的行數,用於資料匯總和分析。
透過這些步驟和範例,可以有效地使用DuckDB進行資料處理和分析,充分發揮其高效能和靈活性。
使用DuckDB進行資料分析與視覺化
DuckDB是一種專為記憶體內處理設計的分析型資料函式庫,能夠高效地處理大量資料。透過其強大的SQL支援和多種擴充功能,DuckDB提供了一種靈活且高效的資料分析解決方案。
資料處理流程
在使用DuckDB進行資料分析時,瞭解資料來源、表格和檢視的資料型別是非常重要的。透過執行計數查詢,可以獲得資料集的基本統計資訊和分佈情況。DuckDB提供了SUMMARIZE子句,能夠為每個欄位提供詳細的統計資訊,包括計數、最小值、最大值、平均值、標準差、近似唯一值、百分位數和空值比例等。
編寫分析查詢
在編寫分析查詢時,可以先從資料的子集開始,使用LIMIT或僅檢視單個輸入檔案。首先定義所需的結果欄位,然後根據需要對資料進行聚合和篩選。DuckDB提供了多種聚合函式,包括傳統的min、avg和sum,以及更進階的函式如histogram、bitstring_agg和approx_count_distinct等。此外,還可以使用視窗函式進行執行總計和與前後行的比較。
使用或處理查詢結果
完成查詢後,可以將結果儲存到檔案或表格中。DuckDB支援多種輸出格式,包括CSV、JSON、Parquet和Excel等。對於較小的結果集,可以使用DuckDB CLI輸出CSV或JSON格式的資料。
資料視覺化
由於一張圖片勝過千行資料,資料視覺化往往是首選。DuckDB內建的bar函式可以渲染內聯條形圖。此外,還可以使用Python和JavaScript生態系統中的工具,如matplotlib、ggplot和d3等,將結果轉換為DataFrame並視覺化。
安裝與使用DuckDB命令列介面
本章節將介紹如何安裝和使用DuckDB命令列介面(CLI)。首先,我們將瞭解DuckDB支援的環境,然後學習如何安裝CLI並執行基本命令。
支援的環境
DuckDB支援多種程式語言和作業系統,包括Linux、Windows和macOS,以及Intel/AMD和ARM架構。目前,DuckDB支援命令列、Python、R、Java、JavaScript、Go、Rust、Node.js、Julia、C/C++、ODBC、JDBC、WASM和Swift等多種環境。
使用DuckDB命令列介面(CLI)
DuckDB命令列介面(CLI)是快速上手的最簡便方式。由於DuckDB是一種嵌入式資料函式庫,在CLI的情況下,它被嵌入到CLI可執行檔中,因此不需要單獨的伺服器安裝。
安裝DuckDB CLI
安裝過程是一個簡單的「複製到」安裝,這意味著不需要安裝程式或函式庫。CLI由一個名為duckdb的單一二進位制檔案組成。下面我們來學習如何在不同作業系統上安裝DuckDB。
在macOS上安裝
在macOS上,官方建議使用Homebrew套件安裝程式,如下所示:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install duckdb
在Linux和Windows上安裝
對於Linux和Windows,有多個不同的套件可供選擇,具體取決於您使用的特定架構和版本。您可以在GitHub發布頁面上找到完整的列表。以下是在Linux上使用AMD64架構執行DuckDB CLI的範例:
wget https://github.com/duckdb/duckdb/releases/download/v0.10.0/duckdb_cli-linux-amd64.zip
unzip duckdb_cli-linux-amd64.zip
./duckdb -version
使用DuckDB CLI
啟動CLI的最簡單方法是直接執行:
duckdb
這將啟動DuckDB和CLI。您應該會看到類別似以下的輸出:
v0.10.0 20b1486d11
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
資料函式庫將是暫時的,所有資料都儲存在記憶體中。當您離開CLI時,它將消失,您可以透過輸入.quit或.exit來離開。
SQL陳述式
您可以直接在命令列中輸入或貼上SQL陳述式,並以分號和換行符結束。在沒有分號的情況下,您可以輸入換行符。它們將直接執行並以緊湊的表格格式輸出結果。您可以按照第2.5.1節的說明更改輸出格式。對於較長時間執行的操作,將顯示進度條。以下是一個簡單的範例,選擇幾個常數值:
select v.* from values (1),(3),(3),(7) as v;
預設情況下,它將以表格格式列印:
┌───────┐
│ col0 │
│ int32 │
├───────┤
│ 1 │
│ 3 │
│ 3 │
│ 7 │
└───────┘
Dot命令
除了SQL陳述式和命令之外,CLI還具有多個特殊的Dot命令。要使用其中一個命令,請在行首緊接著輸入句點(.),然後輸入要執行的命令名稱。命令的其他引數在命令後面以空格分隔輸入。Dot命令必須在一行中輸入,並且在句點之前不能有空白字元。不需要在行尾新增分號,這與正常的SQL陳述式或命令不同。
一些最流行的Dot命令如下所述:
.open關閉目前的資料函式庫檔案並開啟一個新的檔案。.read允許從CLI內讀取SQL檔案以執行。.tables列出目前可用的表格和檢視。.timer on/off切換SQL計時輸出。.mode控制輸出格式。.maxrows控制預設顯示的行數(對於duckbox格式)。.excel在試算表中顯示下一個命令的輸出。.exit、.quit或ctrl-d離開CLI。
完整的概述可以透過.help檢索。
CLI引數
CLI接受可以用於調整資料函式庫模式、控制輸出格式或決定CLI是否進入互動模式的引數。使用方式為duckdb [OPTIONS] FILENAME [COMMANDS]。
一些最流行的CLI引數如下所述:
-readonly以唯讀模式開啟資料函式庫。-json將輸出模式設定為JSON。-line將輸出模式設定為行。-unsigned允許載入未簽名的擴充功能。-s COMMAND或-c COMMAND執行提供的命令,然後離開。這在與.readDot命令結合使用時特別有用,該命令從給定的檔案名稱讀取輸入。
以下是一個範例,示範如何引數化CLI以JSON格式輸出查詢結果:
duckdb --json -c 'select v.* from values (1),(3),(3),(7) as v;'
[{"col0":1},{"col0":3},{"col0":3},{"col0":7}]
要取得可用的CLI引數列表,請呼叫duckdb -help。
DuckDB的擴充系統
DuckDB具有一個擴充系統,用於容納不屬於資料函式庫核心的功能。可以將擴充功能視為可以使用DuckDB安裝的套件。
DuckDB預先載入了多個擴充功能,這些功能根據您使用的發行版而有所不同。您可以透過呼叫duckdb_extensions函式來取得所有可用擴充功能的列表,無論是否已安裝。讓我們首先檢查此函式傳回的欄位。
DESCRIBE
SELECT *
FROM duckdb_extensions();
內容解密:
duckdb_extensions函式:此函式用於檢索DuckDB中所有可用擴充功能的資訊。它提供了有關擴充功能的詳細資訊,例如名稱、是否已安裝等。DESCRIBE陳述式:用於描述查詢結果的欄位結構。在這裡,它被用來檢查duckdb_extensions()函式傳回的欄位,以瞭解可用的擴充功能資訊。SELECT * FROM duckdb_extensions():執行查詢以檢索所有擴充功能的資訊。這讓使用者能夠檢視目前環境中所有可用的擴充功能,無論它們是否已安裝。
透過這些步驟,使用者可以輕鬆地管理和查詢DuckDB中的擴充功能,以滿足不同的資料處理需求。