最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang操作DuckDB實戰(zhàn)案例分享

 更新時間:2025年01月23日 10:15:31   作者:夢想畫家  
DuckDB是一個嵌入式SQL數(shù)據(jù)庫引擎,它與眾所周知的SQLite非常相似,但它是為olap風格的工作負載設計的,DuckDB支持各種數(shù)據(jù)類型和SQL特性,憑借其在以內(nèi)存為中心的環(huán)境中處理高速分析的能力,它迅速受到數(shù)據(jù)科學家和分析師的歡迎,在這篇博文中,我們將探索在Go中使用DuckDB

DuckDB的主要優(yōu)點

  • 內(nèi)存內(nèi)執(zhí)行:DuckDB主要在內(nèi)存中操作,但也支持內(nèi)存外執(zhí)行。這使得它能夠非??焖儆行У貓?zhí)行計算。
  • 完整的SQL支持:DuckDB支持廣泛的SQL特性,這使得它對于各種類型的數(shù)據(jù)操作非常靈活。
  • 事務支持:DuckDB支持事務,這是在許多應用程序中維護數(shù)據(jù)完整性和一致性的關鍵特性。
  • 向量化執(zhí)行:DuckDB使用向量化查詢執(zhí)行,從而提高CPU利用率和性能。
  • 易于集成:DuckDB為多種編程語言提供api,包括Python、R、c++、Rust、Java和Go。這使得將DuckDB集成到現(xiàn)有工作流和系統(tǒng)中變得更加容易。
  • 開源:DuckDB是開源的,這意味著它的源代碼可以免費修改或增強。這允許社區(qū)驅(qū)動的改進和對特定用例的適應性。

環(huán)境準備

在開始使用DuckDB和Go之前,需要安裝DuckDB Go驅(qū)動程序。你可以使用Go的包管理器下載。在終端上運行以下命令:

github.com/marcboeker/go-duckdb
  • 連接數(shù)據(jù)庫
package main


import (
  "database/sql"
  "log"

  _ "github.com/marcboeker/go-duckdb"
)

func main() {
  // Empty datasource means, that DB will be solely in-memory, otherwise you could specify a filename here
  db, err := sql.Open("duckdb", "")
  if err != nil {
    log.Fatal("Failed to connect to database:", err)
  }
  defer db.Close()
}

安裝了驅(qū)動程序后,現(xiàn)在可以從Go應用程序建立到DuckDB的連接。sql.Open() 函數(shù)用于連接到DuckDB,空數(shù)據(jù)源名稱表示我們正在使用內(nèi)存中的數(shù)據(jù)庫,你也可以指定數(shù)據(jù)庫文件名稱,實現(xiàn)數(shù)據(jù)持久化,相對于當前項目所在目錄。

初始化表和數(shù)據(jù)

現(xiàn)在連接已經(jīng)建立,你可以執(zhí)行各種數(shù)據(jù)庫操作了。我們首先創(chuàng)建表,然后插入初始化數(shù)據(jù)進行測試:

package main

import (
	"database/sql"
	"fmt"
	"log"
	"time"

	_ "github.com/marcboeker/go-duckdb"
)

var db *sql.DB
var err error

func main() {
	// Empty datasource means, that DB will be solely in-memory, otherwise you could specify a filename here
	db, err = sql.Open("duckdb", "data.db")
	if err != nil {
		log.Fatal("Failed to connect to database:", err)
	}
	defer db.Close()

	init_data()
}

func init_data() {
	// Create table
	_, err := db.Exec(`
	CREATE TABLE employee (
		id INTEGER,
		name VARCHAR(20),
		start_dt TIMESTAMP,
		is_remote BOOLEAN
	)`)

	if err != nil {
		log.Fatal(err)
	}

	// Insert some data in table
	_, err = db.Exec(`
	INSERT INTO employee (id, name, start_dt, is_remote)
	VALUES
	(1, 'John Doe', '2022-01-01 09:00:00', true),
	(2, 'Jane Smith', '2023-03-15 10:00:00', false)`)
	if err != nil {
		log.Fatal(err)
	}
}

在處理較大的數(shù)據(jù)集時,考慮使用事務和預處理語句以提高效率和安全性。記住,總是處理錯誤并在完成后關閉連接。

查詢單行或多行

要獲取數(shù)據(jù),可以使用QueryRow() 函數(shù)來選擇單行:

func query_one() {
	// Variables to store query result
	var id int
	var name string
	var startDt time.Time
	var isRemote bool

	// Query single row
	if err := db.QueryRow("SELECT id, name, start_dt, is_remote FROM employee WHERE id = ?", 1).Scan(&id, &name, &startDt, &isRemote); err != nil {
		if err == sql.ErrNoRows {
			log.Println("No rows found.")
		} else {
			log.Fatalf("unable to execute query: %v", err)
		}
	} else {
		fmt.Println("Select 1 row result:\nID:", id, "Name:", name, "Start Datetime:", startDt, "Is Remote:", isRemote)
	}
}

不要忘記處理任何錯誤并正確關閉連接和結(jié)果集,如上所示。

要選擇多行,可以使用Query() 函數(shù):

func query_all() {
	// Variables to store query result
	var id int
	var name string
	var startDt time.Time
	var isRemote bool

	// Query multiple rows
	rows, err := db.Query("SELECT id, name, start_dt, is_remote FROM employee")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	// Print the results
	fmt.Println("Results:")
	for rows.Next() {
		err = rows.Scan(&id, &name, &startDt, &isRemote)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("ID:", id, "Name:", name, "Start Datetime:", startDt, "Is Remote:", isRemote)
	}

	err = rows.Err()
	if err != nil {
		log.Fatal(err)
	}
}

我們用SQL命令調(diào)用Query()函數(shù),從employee表中選擇所有記錄。

  • 然后使用rows.Next()進入循環(huán),該循環(huán)遍歷查詢返回的每一行。
  • 在循環(huán)中,我們使用Scan()函數(shù)將當前行的列復制到id、name、startDt和isRemote變量中。
  • 然后使用fmt.Println()函數(shù)打印這些變量。
  • 循環(huán)結(jié)束后,使用rows.Err()檢查迭代過程中的錯誤。如果有錯誤,我們使用log.Fatal(err)打印它。

錯誤處理和事務

在現(xiàn)實世界中,Go代碼必須準備好處理錯誤和處理事務。SQL包提供了所有必要的工具:

func trans_insert() {
	// Error handling and transactions
	tx, err := db.Begin()
	if err != nil {
		log.Fatal(err)
	}
	defer tx.Rollback()

	_, err = tx.Exec(`
	INSERT INTO employee (id, name, start_dt, is_remote)
	VALUES
		(3000000000, 'id int64 instead of int32', '2022-06-17 11:00:00', true)`)
	if err != nil {
		log.Printf("ERROR: %s\n", err.Error()) // Do not fail, just print the error in output
	}

	err = tx.Commit()
	if err != nil {
		log.Fatal(err)
	}
}

此代碼開始事務,嘗試執(zhí)行插入語句,然后提交事務。如果在執(zhí)行期間發(fā)生錯誤,它將回滾在該事務中所做的任何更改。

完整代碼

package main

import (
	"database/sql"
	"fmt"
	"log"
	"time"

	_ "github.com/marcboeker/go-duckdb"
)

var db *sql.DB
var err error

func main() {
	// Empty datasource means, that DB will be solely in-memory, otherwise you could specify a filename here
	db, err = sql.Open("duckdb", "data.db")
	if err != nil {
		log.Fatal("Failed to connect to database:", err)
	}
	defer db.Close()

	// init_data()
	query_one()
	// trans_insert()
	query_all()
}

func init_data() {
	// Create table
	_, err = db.Exec(`
	CREATE TABLE employee (
		id INTEGER,
		name VARCHAR(20),
		start_dt TIMESTAMP,
		is_remote BOOLEAN
	)`)

	if err != nil {
		log.Fatal(err)
	}

	// Insert some data in table
	_, err = db.Exec(`
	INSERT INTO employee (id, name, start_dt, is_remote)
	VALUES
	(1, 'John Doe', '2022-01-01 09:00:00', true),
	(2, 'Jane Smith', '2023-03-15 10:00:00', false)`)
	if err != nil {
		log.Fatal(err)
	}
}

func trans_insert() {
	// Error handling and transactions
	tx, err := db.Begin()
	if err != nil {
		log.Fatal(err)
	}
	defer tx.Rollback()

	_, err = tx.Exec(`
	INSERT INTO employee (id, name, start_dt, is_remote)
	VALUES
		(3000000000, 'id int64 instead of int32', '2022-06-17 11:00:00', true)`)
	if err != nil {
		log.Printf("ERROR: %s\n", err.Error()) // Do not fail, just print the error in output
	}

	err = tx.Commit()
	if err != nil {
		log.Fatal(err)
	}
}

func query_one() {
	// Variables to store query result
	var id int
	var name string
	var startDt time.Time
	var isRemote bool

	// Query single row
	if err := db.QueryRow("SELECT id, name, start_dt, is_remote FROM employee WHERE id = ?", 1).Scan(&id, &name, &startDt, &isRemote); err != nil {
		if err == sql.ErrNoRows {
			log.Println("No rows found.")
		} else {
			log.Fatalf("unable to execute query: %v", err)
		}
	} else {
		fmt.Println("Select 1 row result:\nID:", id, "Name:", name, "Start Datetime:", startDt, "Is Remote:", isRemote)
	}
}

func query_all() {
	// Variables to store query result
	var id int
	var name string
	var startDt time.Time
	var isRemote bool

	// Query multiple rows
	rows, err := db.Query("SELECT id, name, start_dt, is_remote FROM employee")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	// Print the results
	fmt.Println("Results:")
	for rows.Next() {
		err = rows.Scan(&id, &name, &startDt, &isRemote)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("ID:", id, "Name:", name, "Start Datetime:", startDt, "Is Remote:", isRemote)
	}

	err = rows.Err()
	if err != nil {
		log.Fatal(err)
	}
}

最后總結(jié)

DuckDB對Go的支持允許開發(fā)人員直接從他們的Go應用程序中執(zhí)行強大的數(shù)據(jù)分析操作。強大的數(shù)據(jù)管理系統(tǒng)和通用高效的編程語言之間的這種集成為更先進的數(shù)據(jù)處理應用打開了大門。有了本文提供的基礎知識,你就可以開始探索這些可能性了。

以上就是Golang操作DuckDB實戰(zhàn)案例分享的詳細內(nèi)容,更多關于Golang操作DuckDB的資料請關注腳本之家其它相關文章!

相關文章

  • GoFrame框架gset交差并補集使用實例

    GoFrame框架gset交差并補集使用實例

    這篇文章主要為大家介紹了GoFrame框架gset交差并補集使用實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 一文帶你玩轉(zhuǎn)Golang Prometheus Eexporter開發(fā)

    一文帶你玩轉(zhuǎn)Golang Prometheus Eexporter開發(fā)

    本文分兩大塊,一是搞清楚prometheus四種類型的指標Counter,Gauge,Histogram,Summary用golang語言如何構(gòu)造這4種類型對應的指標,二是搞清楚修改指標值的場景和方式,感興趣的可以了解一下
    2023-02-02
  • 一文詳解golang中的gmp模型

    一文詳解golang中的gmp模型

    這篇文章主要介紹了golang中的gmp模型的誕生、概念及調(diào)度講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Go語言如何使用 Viper 來管理配置

    Go語言如何使用 Viper 來管理配置

    在現(xiàn)代軟件開發(fā)中,良好的配置管理可以極大地提升應用的靈活性和可維護性,下面我們就來看看GO語言中如何使用 Viper 來管理配置吧
    2024-11-11
  • Golang 斷言與閉包使用解析

    Golang 斷言與閉包使用解析

    這篇文章主要介紹了Golang 斷言與閉包使用解析,Go中的斷言用于判斷變量的類型,更多相關內(nèi)容需要的朋友可以參考一下
    2022-07-07
  • Golang中的同步工具sync.Map示例詳解

    Golang中的同步工具sync.Map示例詳解

    sync.Map是Golang標準庫提供的并發(fā)安全的Map類型,可以在多個goroutine并發(fā)讀寫Map的場景下不需要加鎖,這篇文章主要介紹了Golang中的同步工具sync.Map詳解,需要的朋友可以參考下
    2023-05-05
  • go語言中切片的長度和容量的區(qū)別

    go語言中切片的長度和容量的區(qū)別

    這篇文章主要介紹了go語言中切片的長度和容量的區(qū)別,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go中字符串處理?fmt.Sprintf與string.Builder的區(qū)別對比分析

    Go中字符串處理?fmt.Sprintf與string.Builder的區(qū)別對比分析

    在Go語言中,我們通常會遇到兩種主要的方式來處理和操作字符串:使用fmt.Sprintf函數(shù)和string.Builder類型,本文給大家介紹它們在性能和用法上有一些關鍵區(qū)別,感興趣的朋友跟隨小編一起看看吧
    2023-11-11
  • Go的os/exec執(zhí)行超時導致程序死機的解決方案

    Go的os/exec執(zhí)行超時導致程序死機的解決方案

    這篇文章主要介紹了Go的os/exec執(zhí)行超時導致程序死機的幾種解決方案,文中通過代碼示例給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-04-04
  • Go語言中uintptr和unsafe.Pointer的區(qū)別的實現(xiàn)小結(jié)

    Go語言中uintptr和unsafe.Pointer的區(qū)別的實現(xiàn)小結(jié)

    Go語言中的uintptr和unsafe.Pointer都是用于底層內(nèi)存操作的類型,本文就來介紹一下uintptr和unsafe.Pointer的區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2025-10-10

最新評論

和林格尔县| 梁山县| 呼图壁县| 乌鲁木齐县| 攀枝花市| 永春县| 平遥县| 东乡县| 桑日县| 枝江市| 剑阁县| 舟曲县| 阿城市| 伊川县| 平阳县| 孝义市| 澄城县| 闵行区| 循化| 三亚市| 南乐县| 石棉县| 上高县| 济南市| 雷山县| 鸡西市| 南雄市| 花垣县| 绥化市| 杭锦后旗| 万全县| 石城县| 无锡市| 凤庆县| 通渭县| 台前县| 石泉县| 阿鲁科尔沁旗| 绥棱县| 肃南| 铅山县|