DuckDB簡介
1. 概述
在本教程中,我們將了解一個名為DuckDB的分析關係型資料庫。我們將探索它的優勢,並了解它如何成為分析任務的有效解決方案。之後,我們將逐步完成安裝和一些基本操作。
2.DuckDB是什麼?
DuckDB是一個記憶體分析型關係資料庫,主要用於資料分析。由於其列式儲存性質(單獨儲存每列的資料),它被視為分析資料庫。相較之下,傳統的關聯式資料庫採用基於行的存儲,逐行儲存資料。
DuckDB 的優點包括:
- 快速查詢-DuckDB利用列式向量化查詢執行引擎來最佳化大批量的資料查詢。
- SQL相容性-DuckDB支援標準SQL查詢,例如聚合和視窗函數,非常適合熟悉SQL的資料分析師。
- 快速部署 - DuckDB 具有最小的外部依賴性,並且在我們的應用程式進程中運行,無需單獨的資料庫實例,從而使部署和整合變得簡單。
- 免費 – DuckDB 是一個開源項目,可供所有人免費使用。其完整原始程式碼可在 GitHub 上存取以供探索和貢獻。
3.DuckDB安裝
DuckDB 提供了各種安裝選項來適合我們的環境。我們將在這裡示範兩種常見的安裝方法。
3.1.命令列
對於Windows用戶,我們可以使用WinGet套件管理器安裝DuckDB。我們所需要做的就是使用管理員權限開啟命令提示字元並執行以下命令:
winget install DuckDB.cli
在 Mac OS 上,我們可以使用 Homebrew 安裝它:
brew install duckdb
完成DuckDB CLI的安裝後, brew
會自行將二進位路徑加入現有環境變數。我們可以開啟一個新的 shell 會話並透過執行以下命令來執行 DuckDB CLI:
duckdb
3.2.爪哇
DuckDB 可以與 Java 集成,無需安裝單獨的資料庫實例。首先,我們在pom.xml
中包含以下DuckDB JDBC相依性:
<dependency>
<groupId>org.duckdb</groupId>
<artifactId>duckdb_jdbc</artifactId>
<version>0.10.0</version>
</dependency>
我們可以載入 DuckDB JDBC 驅動程序,然後透過以下 JDBC URL 建立 JDBC 連線:
Class.forName("org.duckdb.DuckDBDriver");
Connection conn = DriverManager.getConnection("jdbc:duckdb:");
當我們連接到 DuckDB 時,預設情況下它會自動建立一個記憶體資料庫實例。但是,一旦 DuckDB 進程完成,實例中保留的所有資料都會遺失。要將資料儲存到磁碟中,我們可以在連接 URL 中的冒號後面附加一個資料庫名稱:
Connection conn = DriverManager.getConnection("jdbc:duckdb:/test_duckdb");
在此範例中,DuckDB 在根目錄中建立一個名為test_duckdb
的資料庫檔案。由於這是一個 JDBC 函式庫,我們可以透過建立 SQL Statement
並執行它來取得ResultSet
來查詢資料。下面是一個取得目前日期的簡單 JDBC 範例:
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT current_date");
Date currentDate = rs.next() ? rs.getDate(1) : null;
在本教學的後續部分中,我們可以在 Java 中使用相同的 JDBC 方法執行 SQL 語句。
4. 資料導入
讓我們繼續將一些資料導入 DuckDB。它可以處理各種資料格式,從而簡化從外部資料來源的匯入。
4.1. CSV 檔案
CSV 是一種用於儲存表格資料的常見資料格式。假設我們有以下包含客戶資料的 CSV 檔案:
CustomerId,FirstName,LastName,Gender
101,John,Smith,Male
102,Sarah,Jones,Female
...
我們可以使用 SQL 函數read_csv
將資料從 CSV 檔案匯入到 DuckDB 表customer
中:
CREATE TABLE customer AS
SELECT * FROM read_csv('customer.csv')
DuckDB 可以從 CSV 檔案的標題行找出架構。標題名稱被視為表格列名稱,而後續行則被視為資料行。
4.2 JSON 文件
另一種流行的儲存和共享資料的方式是 JSON。例如,我們採用以下product.json
JSON 檔案:
[
{
"productId": 1,
"productName":"EZ Curl Bar",
"category": "Sports Equipment"
},
{
"productId": 2,
"productName": "7' Barbell",
"category": "Sports Equipment"
}
]
與CSV匯入類似,我們可以執行一條SQL語句將資料匯入DuckDB表product
:
CREATE TABLE product AS
SELECT * FROM read_json('product.json')
就像 CSV 一樣,DuckDB 根據 JSON 屬性名稱自動從 JSON 檔案中找出架構。
4.3. INSERT
語句
我們可以使用insert
語句為 DuckDB 表新增數據,因為它是 SQL 關聯式資料庫系統。下面的範例說明了建立一個定義customer
和product
之間關係的purchase
表並填入幾行資料:
CREATE TABLE purchase(customerId BIGINT, productId BIGINT);
INSERT INTO purchase(customerId, productId) VALUES (101,1);
INSERT INTO purchase(customerId, productId) VALUES (102,1);
INSERT INTO purchase(customerId, productId) VALUES (102,2);
5. 資料查詢
載入資料後,我們現在將探索查詢 DuckDB 並分析我們的資料。
5.1.加盟營運
除了將外部資料匯入到DuckDB之外,我們還可以直接使用外部資料。根據前面的範例,我們將利用上一節中的三個資料來源。現在,讓我們加入這些資料來源來收集有關客戶產品的資訊。
SELECT C.firstName, C.lastName, P.productName
FROM read_csv('customer.csv') AS C, read_json('product.json') AS P, purchase S
WHERE S.customerId = C.customerId
AND S.productId = P.productId
執行後,我們將看到以下查詢結果,顯示客戶名稱及其對應的產品購買情況:
名 | 姓 | 產品名稱 |
---|---|---|
約翰 | 史密斯 | EZ 彎桿 |
莎拉 | 瓊斯 | 7′槓鈴 |
莎拉 | 瓊斯 | EZ 彎桿 |
5.2.聚合函數
DuckDB 提供了一組豐富的聚合函數來對行組執行計算。讓我們探討一下具有這些函數的範例:
SELECT P.productName, COUNT(*) AS purchaseCount
FROM customer C, product P, purchase S
WHERE S.customerId = C.customerId
AND S.productId = P.productId
GROUP BY P.productName
ORDER BY COUNT(*) DESC
查詢統計每個商品的購買次數,並依購買次數降序排列:
產品名稱 | 購買數量 |
---|---|
EZ 彎桿 | 2 |
7′槓鈴 | 1 |
6. 數據導出
在資料分析任務中,我們經常需要將聚合資料匯出到其他應用程式以進行進一步分析。
讓我們逐步了解以各種格式從 DuckDB 匯出資料的過程。在我們的範例中,我們首先建立一個資料庫視圖,以便於稍後說明導出:
CREATE VIEW purchase_view AS
SELECT P.productName, COUNT(*) AS purchaseCount
FROM customer C, product P, purchase S
WHERE S.customerId = C.customerId
AND S.productId = P.productId
GROUP BY P.productName
ORDER BY COUNT(*) DESC;
6.1. CSV 檔案
在 DuckDB 中將資料匯出到 CSV 檔案非常簡單。我們可以執行以下簡單的 SQL 將資料庫視圖purchase_view
中的所有資料複製到位於根目錄中的 CSV 檔案:
COPY purchase_view TO '/output.csv'
6.2. JSON 文件
要將資料匯出到 JSON 文件,我們需要包含一個附加選項array
來指定將資料寫入 JSON 陣列。這可確保我們匯出的 JSON 檔案具有適當的結構:
COPY (SELECT * FROM purchase_view WHERE purchaseCount > 1) TO '/output.json' (array true);
我們可以根據select
查詢的條件複製部分結果,而不是匯出所有資料。
七、結論
在這篇文章中,我們了解了DuckDB資料庫及其優點。我們也透過說明性範例研究了一些基本操作。
與往常一樣,所有程式碼都可以在 GitHub 上取得。