DuckDB 作為嵌入式分析型資料函式庫,能有效處理和分析來自 CSV、JSON、Parquet 等多種格式的資料。它與 Python 等程式語言的整合性,讓開發者能輕鬆運用其強大的 SQL 查詢功能進行資料分析和轉換,無需將資料複製到記憶體中。DuckDB 的高效能和易用性,使其在資料分析、資料轉換和雲端佈署等場景中皆有優異表現,尤其適用於處理大量資料。此外,DuckDB 也支援 dlt 和 dbt 等工具,方便資料匯入和轉換,並可透過 Streamlit 建構互動式資料應用。

DuckDB:資料處理的核心樞紐

資料來源與轉換

DuckDB 作為資料處理的核心工具,能夠有效地處理多種資料來源,並進行必要的轉換。資料來源的多樣性使得資料處理變得複雜,但 DuckDB 提供了強大的功能來簡化這一過程。

資料來源

DuckDB 可處理的資料來源包括但不限於:

  • CSV 檔案
  • JSON 檔案
  • Parquet 檔案
  • SQLite 資料函式庫
  • Excel 檔案

這些資料來源可以透過 DuckDB 的強大查詢功能進行處理和分析。

資料轉換

在資料處理過程中,資料轉換是一個重要的步驟。DuckDB 提供了多種方式來進行資料轉換,包括:

  • 將 CSV 檔案轉換為 Parquet 格式
  • 解析巢狀的 JSON 資料
  • 查詢和轉換 SQLite 資料函式庫中的資料

程式語言支援

DuckDB 不僅支援多種資料來源和轉換,還與多種程式語言整合,包括 Python。透過 Python 使用者可以輕鬆地利用 DuckDB 的強大功能,進行資料分析和處理。

使用 DuckDB 的優勢

使用 DuckDB 的主要優勢包括:

  1. 高效能:DuckDB 設計用於高效處理大量資料。
  2. 易用性:提供了簡單直觀的 SQL 介面,方便使用者進行資料查詢和分析。
  3. 靈活性:支援多種資料來源和格式,並且可以與多種程式語言整合。

實際應用案例

在實際應用中,DuckDB 可以用於多種場景,例如:

  • 資料分析:利用 DuckDB 的 SQL 功能進行複雜的資料分析。
  • 資料轉換:將不同格式的資料轉換為統一的格式,以便進一步處理。
  • 雲端佈署:透過 MotherDuck 將 DuckDB 佈署在雲端,實作資料的分享和管理。

使用DuckDB建構資料處理流程與資料應用開發

前言:DuckDB的崛起

DuckDB自2018年誕生以來,以其創新性的設計理念和卓越的效能迅速獲得了廣泛關注。作為一個內嵌式分析型資料函式庫系統,DuckDB打破了傳統資料函式庫系統的思維模式,致力於提供簡便易用且高效能的資料處理解決方案。由Mark Raasveldt和Hannes Mühleisen建立的DuckDB,不僅在開源社群中獲得了極高的評價,更是在眾多企業和開發者中得到廣泛應用。

建構資料處理流程

資料引入與dlt工具

建構資料處理流程的第一步是資料引入。dlt(Data Load Tool)是一個強大的工具,能夠簡化資料來源的接入過程。首先,我們需要安裝支援的資料來源套件。例如,若要從特定的API或資料函式庫匯入資料,則需安裝對應的dlt套件。

pip install dlt[postgresql]

接著,我們可以建立一個簡單的pipeline來匯入資料。以下是一個基本的範例:

import dlt

def main():
    # 定義pipeline
    pipeline = dlt.pipeline(
        pipeline_name='example_pipeline',
        destination='duckdb',
        dataset_name='example_dataset'
    )

    # 執行pipeline
    pipeline.run(data=[{'id': 1, 'name': 'example'}])

if __name__ == '__main__':
    main()

資料解密:

此範例展示瞭如何使用dlt建立一個簡單的資料匯入流程。首先,我們定義了一個名為example_pipeline的pipeline,並指定了目的地為DuckDB以及資料集名稱。接著,透過pipeline.run()方法匯入了一筆範例資料。

資料轉換與dbt

在完成資料引入後,下一步是進行資料轉換和建模。dbt(Data Build Tool)是一個專門用於資料轉換和建模的工具,能夠有效地管理和執行SQL轉換邏輯。

首先,我們需要設定一個dbt專案:

dbt init example_project

在專案中,我們可以定義資料來源(sources)和轉換模型(models)。例如,定義一個簡單的模型:

-- models/example_model.sql
SELECT 
    id,
    name,
    UPPER(name) AS name_upper
FROM 
    {{ source('example_dataset', 'example_table') }}

資料解密:

此SQL模型展示瞭如何從來源資料表中選取欄位並進行簡單的轉換(如將名字轉換為大寫)。透過dbt,我們可以有效地管理和版本控制我們的資料轉換邏輯。

資料流程協調與Dagster

為了更好地管理和執行資料處理流程,我們可以使用Dagster這類別的工作流程協調工具。Dagster允許我們定義資產(assets)、管理工作依賴關係,並執行複雜的計算。

from dagster import asset

@asset
def example_asset():
    # 執行一些計算或資料處理邏輯
    return [{'id': 1, 'result': 'success'}]

資料解密:

此範例展示瞭如何使用Dagster定義一個簡單的資產。透過資產的概念,我們可以將複雜的資料處理邏輯模組化並加以管理。

建構與佈署資料應用

使用Streamlit建構自定義資料應用

Streamlit是一個強大的工具,能夠讓開發者快速建立互動式的資料應用。首先,我們需要安裝Streamlit:

pip install streamlit

接著,可以建立一個簡單的應用:

import streamlit as st

def main():
    st.title('Example Data App')
    st.write('Hello, World!')

if __name__ == '__main__':
    main()

資料解密:

此範例展示瞭如何使用Streamlit建立一個簡單的網頁應用。透過Streamlit,我們可以輕鬆地建立互動式的使用者介面,並結合資料視覺化元件(如plot.ly)來呈現資料洞察。

大型資料集的效能考量

載入與查詢大型資料集

當處理大型資料集時,效能成為了一個重要的考量。DuckDB提供了多種最佳化手段,例如使用Parquet格式儲存資料,以及利用查詢計畫和執行最佳化技術來提升查詢效能。

例如,載入Stack Overflow資料集到DuckDB:

COPY stack_overflow_data FROM 'stackoverflow.csv' WITH (FORMAT CSV, HEADER);

資料解密:

此SQL指令展示瞭如何將CSV檔案匯入DuckDB中。透過適當的檔案格式選擇和查詢最佳化,我們可以顯著提升大型資料集的處理效能。

前言

本文主要介紹DuckDB,一種現代化、快速的嵌入式分析型資料函式庫。它可以在本地執行,輕鬆處理來自多種來源的龐大資料,包括JSON、CSV、Parquet、SQLite和Postgres。DuckDB與Python和R生態系統整合,能夠在不複製資料的情況下查詢記憶體中的資料框架。您不再需要為日常資料處理啟動雲端資料倉儲;只需在本地或雲端執行DuckDB即可。

DuckDB讓您能夠毫無阻礙地解決關聯式資料分析任務。它非常易於使用和學習。最重要的是,您可以將其嵌入Python環境和應用程式中,就像SQLite一樣。我們堅信,我們在教學DuckDB方面達到了最佳狀態,不僅涵蓋了其CLI嵌入模式、Python整合,還包括了建立資料管道和處理資料的能力,同時也引導讀者深入瞭解DuckDB的現代SQL。

雖然我們都是長期從事資料領域的專家和教育者,但我們來自不同的領域——圖形、即時欄位和關聯式資料函式庫——然而,我們都在DuckDB中發現了值得探討的價值。我們不僅在專業領域之外喜歡使用DuckDB,也將其視為工作中的有用工具。

致謝

首先要感謝我們的技術編輯Jordan Tigani,MotherDuck的共同創始人兼CEO。他的嚴謹工作和反饋使我們的範例和寫作變得更好。也非常感謝其他技術審閱者,他們仔細審閱了章節並提供了反饋,尤其是Marcos Ortiz、Georg Heiler和Jacob Matson對原始提案的審閱,以及Dirk Gomez對所有程式碼的檢查。

Mark Raasveldt、Hannes Mühleisen和Alex Monahan的著作和解釋對我們幫助很大,讓我們更深入地瞭解了DuckDB的內部工作原理、背後的理念以及一些我們以前不知道的SQL技巧。感謝你們!

同時也感謝Ryan Boyd和Mehdi Quazza,他們不僅提供了寶貴的反饋,還幫助我們讓更多人瞭解這本文。

我們還要感謝Manning的編輯團隊,尤其是Rhonda Mason和Jonathan Gennick,他們對我們的處理非常積極,以及Christian Berk的勤奮校對和快速反饋。Michael Hunger和Michael Simons很高興我們的Neo4j同事雖然可能對我們的觀點有些懷疑,但他們有足夠的自信來承認圖形和關聯式方法可以共存。DuckDB對我們思考如何對使用者軟體產生同理心產生了深遠影響。

感謝所有審閱者——Andrej Abramušić、Abhilash Babu Jyotheendra Babu、Anjan Bacchu、Chris Bolyard、Thiago Britto Borges、Nadir Doctor、Didier Donsez、Dirk Gómez、Simon Hewitt、Andrew Judd、Madiha Khalid、Simeon Leyzerzon、Noel Llevares、Sebastian Maier、Eli Mayost、Sumit Pal、Anup K. Parikh、Sasha Sankova、William Jamir Silva、Ganesh Swaminathan、Mary Anne Thygesen、Rohini Uppuluri、Ankit Virmani、Wondi Wolde和Heng Zhang——你們的建議讓這本文變得更好。

當然,像這樣一本文,在工作之餘撰寫,需要犧牲很多個人時間和私人生活。我們感謝我們的家人對我們這些瘋狂想法的持續支援。

關於這本文

我們並不想寫一本參考書(那是檔案該做的事),而是希望與大家分享我們在使用DuckDB時的興奮和樂趣,讓您在每一頁都能學到新東西,同時享受我們在寫作過程中的樂趣。本文節奏快,資訊豐富,實作性強,範例易於理解且實用。

誰應該閱讀這本文

本文的理想讀者是資料工程師、資料科學家或開發人員,他們有興趣在不需要設定基礎設施的情況下高效分析現有的結構化資料。他們應該熟悉命令列工具,最好還熟悉Python。我們將涵蓋大量的SQL,從簡單的子句開始,一直到進階的分析陳述式。DuckDB可在所有主要作業系統上執行,無需安裝過程;下載並執行可執行檔即可。我們的關於MotherDuck(無伺服器分析平台)的章節需要建立帳戶,如果您想試用它。

本文的組織結構:路線圖

我們首先在第1章和第2章中對DuckDB進行了溫和的介紹,介紹了它的使用案例及其在現代資料管道中的地位。首先,我們將確保您能夠使用DuckDB CLI,然後在第3章中介紹SQL。我們將涵蓋基本的子句和陳述式,然後在第4章中使用進階聚合、視窗函式、遞迴SQL等進入進階資料分析的世界。當然,我們還將介紹DuckDB帶來的供應商特定的開發人員友好擴充套件。#### 內容解密:

  1. 本文主要針對想要高效分析結構化資料的讀者。
  2. 介紹了DuckDB的功能和使用案例。
  3. 涵蓋了SQL的基本和進階用法。
  4. 提供了實用的範例和操作。
-- SQL 範例:查詢範例
SELECT * FROM 資料表;

內容解密:

  • 上述SQL陳述式用於查詢資料表中的所有資料。
  • SELECT 是用來選擇資料的關鍵字。
  • * 代表選擇所有欄位。
  • FROM 指定了要查詢的資料表。
# Python 範例:使用DuckDB查詢
import duckdb

# 建立連線
con = duckdb.connect(database=':memory:')

# 查詢範例
con.execute("SELECT * FROM 資料表")
result = con.fetchall()
print(result)

內容解密:

  • 上述Python程式碼展示瞭如何使用DuckDB進行查詢。
  • 首先匯入了 duckdb 模組。
  • 使用 duckdb.connect 建立了一個連線,指定了資料函式庫為記憶體中的資料函式庫。
  • 使用 con.execute 執行SQL查詢,並使用 con.fetchall() 取得查詢結果。
  • 最後列印出查詢結果。

本文簡介

DuckDB 是一個多面性的工具,其中一個特點是它不強制使用特定的持久化儲存方式。在第 5 章中,我們將詳細討論如何使用 SQL 引擎處理多種不同的檔案格式,而無需將資料匯入表格中。

第 6 章將探討 DuckDB 的 Python 整合,接著在第 7 章中,我們將轉向雲端技術,介紹 MotherDuck。在此之後,我們將具備建立有效資料管道(第 8 章)和佈署資料應用程式(第 9 章)的所有必要工具。

在第 10 章中,我們將退一步,討論處理大型資料集時的注意事項,並應用我們迄今為止所學到的知識。DuckDB 不僅提供了一個 CLI 和出色的 Python 整合,還有 Java、C、C++、Julia、Rust 等多種語言的整合。在附錄中,我們將介紹這些整合,特別是如何從 Java 中使用 DuckDB。

程式碼說明

本文包含許多原始碼範例,無論是在編號列表中還是在正文中。這些原始碼都使用固定寬度的字型,以區別於普通文字。有時,程式碼也會以粗體顯示,以突出顯示與前一步驟相比發生了變化的部分,例如在現有程式碼行中增加了新功能。

程式碼格式處理

在多數情況下,原有的原始碼已經被重新格式化;我們增加了換行符並重新調整了縮排,以適應書籍的可用頁面空間。在極少數情況下,即使這樣做仍然不夠,列表中還包括了行接續標記( ➥ )。在這些情況下,您可能需要刪除由該標記引入的額外空格,以使程式碼能夠正常執行,或修復過長的 URL。

此外,當程式碼在文字中被描述時,原始碼中的註解通常會被刪除。許多列表都附有程式碼註解,突出了重要的概念。

線上論壇

作者簡介

馬克·尼德漢姆(Mark Needham)

馬克是 ClickHouse 的產品行銷工程師,他創作了有關即時資料倉儲的短影片並撰寫了相關的部落格文章。他還致力於改善開發者體驗,透過對產品的調整和檔案的改進來簡化入門體驗。

馬克在資料基礎設施領域工作了十多年,先是在 Neo4j 從事圖資料函式庫的工作,然後在 StarTree 從事與 Apache Pinot 相關的即時分析工作。在過去的 15 年裡,他一直透過 markhneedham.com 這個部落格分享他撰寫軟體的經驗,並在 https://www.youtube.com/@learndatawithmark 上創作了許多關於資料和 AI 主題的教育影片。

他在推特上的暱稱是 @markhneedham。

米夏埃爾·亨格(Michael Hunger)

米夏埃爾對軟體開發充滿熱情已經超過 35 年。在過去的 14 年裡,他一直致力於開源的 Neo4j 圖資料函式庫,擔任過多個角色,最近擔任產品創新和開發者產品策略負責人。在加入 Neo4j 之前,他曾參與大型 Java 專案的諮詢工作,並為 Oracle、Informix 和 MySQL 資料函式庫編寫了大量的 SQL 程式碼。他還在 2006 年建立了 Jequel SQL DSL,後來與類別似的專案合併。

作為一名開發者,米夏埃爾喜歡多個程式語言、工具和技術,每天學習新的知識,參與令人興奮和雄心勃勃的開源專案,並為軟體相關的書籍和文章做出貢獻。他的興趣涵蓋了 Java、Kotlin、GraphQL、圖資料函式庫、生成式 AI 和現代資料分析等領域。米夏埃爾曾在多個會議上發表演講,並幫助組織了幾次會議。他的努力使他成為了 Java Champions 計畫的一員;12 年來,他一直為 Java SPEKTRUM 印刷雜誌撰寫有關「Effective Java」的雙月欄目。米夏埃爾還透過在當地學校舉辦每週一次的僅限女孩參加的程式設計課程,幫助孩子們學習程式設計。

您可以在他的部落格 https://www.jexp.de 上找到更多關於米夏埃爾的寫作和專案資訊。

米夏埃爾·西蒙斯(Michael Simons)

米夏埃爾·西蒙斯是一位 Java 冠軍,也是 Neo4j 的高階軟體工程師,他作為開發者已經工作了 20 多年。在 Neo4j 的工作中,他是將 Neo4j 整合到更廣泛的 Java 生態系統中的重要成員。

在進入圖資料函式庫領域之前,他曾在德國公用事業部門工作,利用 SQL 為大型德國輸電網營運商和能源生產商計算和預測能源使用量,那時分析型資料函式庫尚未成為主流。直到今天,他仍然喜歡使用 SQL(以及 Cypher)的宣告式特性來向機器詢問答案,而不是指示它們產生結果。

米夏埃爾是一位知名的會議演講者,多年來一直在 Java 和資料函式庫(關係型和圖型均有涉及)之間架起橋樑。他是暢銷書《Spring Boot 2》的作者,並與他人共同撰寫了《arc42 by Example》這本關於軟體架構檔案的書。他還在 info.michael-simons.eu 上寫部落格。

在剩下的閒暇時間裡,米夏埃爾仍然夢想成為一名業餘運動員。當他沒有訓練參加下一場馬拉松比賽時,他會使用 DuckDB 在 biking.michael-simons.eu/history 上記錄自己的進步。