亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

DuckDB的主要優(yōu)點(diǎn)

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

環(huán)境準(zhǔn)備

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

github.com/marcboeker/go-duckdb
  • 連接數(shù)據(jù)庫(kù)
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ū)動(dòng)程序后,現(xiàn)在可以從Go應(yīng)用程序建立到DuckDB的連接。sql.Open() 函數(shù)用于連接到DuckDB,空數(shù)據(jù)源名稱(chēng)表示我們正在使用內(nèi)存中的數(shù)據(jù)庫(kù),你也可以指定數(shù)據(jù)庫(kù)文件名稱(chēng),實(shí)現(xiàn)數(shù)據(jù)持久化,相對(duì)于當(dāng)前項(xiàng)目所在目錄。

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

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

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í),考慮使用事務(wù)和預(yù)處理語(yǔ)句以提高效率和安全性。記住,總是處理錯(cuò)誤并在完成后關(guān)閉連接。

查詢單行或多行

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

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)
	}
}

不要忘記處理任何錯(cuò)誤并正確關(guān)閉連接和結(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()進(jìn)入循環(huán),該循環(huán)遍歷查詢返回的每一行。
  • 在循環(huán)中,我們使用Scan()函數(shù)將當(dāng)前行的列復(fù)制到id、name、startDt和isRemote變量中。
  • 然后使用fmt.Println()函數(shù)打印這些變量。
  • 循環(huán)結(jié)束后,使用rows.Err()檢查迭代過(guò)程中的錯(cuò)誤。如果有錯(cuò)誤,我們使用log.Fatal(err)打印它。

錯(cuò)誤處理和事務(wù)

在現(xiàn)實(shí)世界中,Go代碼必須準(zhǔn)備好處理錯(cuò)誤和處理事務(wù)。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)
	}
}

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

完整代碼

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

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

相關(guān)文章

  • Golang開(kāi)發(fā)庫(kù)的集合及作用說(shuō)明

    Golang開(kāi)發(fā)庫(kù)的集合及作用說(shuō)明

    這篇文章主要為大家介紹了Golang開(kāi)發(fā)golang庫(kù)的集合及簡(jiǎn)單的作用說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • Go語(yǔ)言中的函數(shù)詳解

    Go語(yǔ)言中的函數(shù)詳解

    函數(shù)是基本的代碼塊,用于執(zhí)行一個(gè)任務(wù)。本文詳細(xì)講解了Go語(yǔ)言中的函數(shù),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • golang占位符%v、%+v、%#v舉例詳解

    golang占位符%v、%+v、%#v舉例詳解

    這篇文章主要給大家介紹了關(guān)于golang占位符%v、%+v、%#v的相關(guān)資料,Go語(yǔ)言中的占位符通常用于格式化輸出,它們以%開(kāi)頭,后跟一個(gè)字符,表示要轉(zhuǎn)換的數(shù)據(jù)類(lèi)型,需要的朋友可以參考下
    2024-05-05
  • golang基于websocket通信tcp keepalive研究記錄

    golang基于websocket通信tcp keepalive研究記錄

    這篇文章主要為大家介紹了golang基于websocket通信tcp keepalive研究記錄,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 基于Go語(yǔ)言實(shí)現(xiàn)高性能文件上傳下載系統(tǒng)

    基于Go語(yǔ)言實(shí)現(xiàn)高性能文件上傳下載系統(tǒng)

    在Web應(yīng)用開(kāi)發(fā)中,文件上傳下載是一個(gè)非常常見(jiàn)的需求,本文將介紹如何使用Go語(yǔ)言實(shí)現(xiàn)一個(gè)安全、高效的本地文件存儲(chǔ)系統(tǒng),感興趣的小伙伴可以了解下
    2025-03-03
  • GoLang中Strconv庫(kù)有哪些常用方法

    GoLang中Strconv庫(kù)有哪些常用方法

    這篇文章主要介紹了GoLang中Strconv庫(kù)有哪些常用方法,strconv庫(kù)實(shí)現(xiàn)了基本數(shù)據(jù)類(lèi)型與其字符串表示的轉(zhuǎn)換,主要有以下常用函數(shù):?Atoi()、Itia()、parse系列、format系列、append系列
    2023-01-01
  • Go基礎(chǔ)教程系列之WaitGroup用法實(shí)例詳解

    Go基礎(chǔ)教程系列之WaitGroup用法實(shí)例詳解

    這篇文章主要介紹了Go基礎(chǔ)教程系列之WaitGroup用法實(shí)例詳解,需要的朋友可以參考下
    2022-04-04
  • Golang中interface{}轉(zhuǎn)為數(shù)組的操作

    Golang中interface{}轉(zhuǎn)為數(shù)組的操作

    這篇文章主要介紹了Golang中interface{}轉(zhuǎn)為數(shù)組的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Golang六個(gè)常用接口的使用總結(jié)

    Golang六個(gè)常用接口的使用總結(jié)

    在這篇文章中,小編來(lái)帶大家學(xué)習(xí)幾個(gè)Go標(biāo)準(zhǔn)庫(kù)的接口,看看Go標(biāo)準(zhǔn)庫(kù)是如何定義接口,以加深對(duì)Go語(yǔ)言接口的理解,感興趣的小伙伴快跟隨小編一起了解一下吧
    2023-07-07
  • Golang并發(fā)編程重點(diǎn)講解

    Golang并發(fā)編程重點(diǎn)講解

    這篇文章主要介紹了Golang并發(fā)編程,在許多環(huán)境中,實(shí)現(xiàn)對(duì)共享變量的正確訪問(wèn)所需要的微妙之處使并發(fā)編程變得困難。Go鼓勵(lì)一種不同的方法,在這種方法中,共享值在通道中傳遞,實(shí)際上,從不由單獨(dú)的執(zhí)行線程主動(dòng)共享
    2023-04-04

最新評(píng)論