DuckDB:Golang操作DuckDB实战案例
DuckDB是一个嵌入式SQL数据库引擎。它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的。DuckDB支持各种数据类型和SQL特性。凭借其在以内存为中心的环境中处理高速分析的能力,它迅速受到数据科学家和分析师的欢迎。在这篇博文中,我们将探索在Go中使用DuckDB。

DuckDB的主要优点
- 内存内执行:DuckDB主要在内存中操作,但也支持内存外执行。这使得它能够非常快速有效地执行计算。
- 完整的SQL支持:DuckDB支持广泛的SQL特性,这使得它对于各种类型的数据操作非常灵活。
- 事务支持:DuckDB支持事务,这是在许多应用程序中维护数据完整性和一致性的关键特性。
- 向量化执行:DuckDB使用向量化查询执行,从而提高CPU利用率和性能。
- 易于集成:DuckDB为多种编程语言提供api,包括Python、R、c++、Rust、Java和Go。这使得将DuckDB集成到现有工作流和系统中变得更加容易。
- 开源:DuckDB是开源的,这意味着它的源代码可以免费修改或增强。这允许社区驱动的改进和对特定用例的适应性。

环境准备
在开始使用DuckDB和Go之前,需要安装DuckDB Go驱动程序。你可以使用Go的包管理器下载。在终端上运行以下命令:
github.com/marcboeker/go-duckdb
- 连接数据库
package mainimport ("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 heredb, err := sql.Open("duckdb", "")if err != nil {log.Fatal("Failed to connect to database:", err)}defer db.Close()
}
安装了驱动程序后,现在可以从Go应用程序建立到DuckDB的连接。sql.Open() 函数用于连接到DuckDB,空数据源名称表示我们正在使用内存中的数据库,你也可以指定数据库文件名称,实现数据持久化,相对于当前项目所在目录。
初始化表和数据
现在连接已经建立,你可以执行各种数据库操作了。我们首先创建表,然后插入初始化数据进行测试:
package mainimport ("database/sql""fmt""log""time"_ "github.com/marcboeker/go-duckdb"
)var db *sql.DB
var err errorfunc main() {// Empty datasource means, that DB will be solely in-memory, otherwise you could specify a filename heredb, 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)}
}
在处理较大的数据集时,考虑使用事务和预处理语句以提高效率和安全性。记住,总是处理错误并在完成后关闭连接。
查询单行或多行
要获取数据,可以使用QueryRow() 函数来选择单行:
func query_one() {// Variables to store query resultvar id intvar name stringvar startDt time.Timevar isRemote bool// Query single rowif 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)}
}
不要忘记处理任何错误并正确关闭连接和结果集,如上所示。
要选择多行,可以使用Query() 函数:
func query_all() {// Variables to store query resultvar id intvar name stringvar startDt time.Timevar isRemote bool// Query multiple rowsrows, err := db.Query("SELECT id, name, start_dt, is_remote FROM employee")if err != nil {log.Fatal(err)}defer rows.Close()// Print the resultsfmt.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命令调用Query()函数,从employee表中选择所有记录。
- 然后使用rows.Next()进入循环,该循环遍历查询返回的每一行。
- 在循环中,我们使用Scan()函数将当前行的列复制到id、name、startDt和isRemote变量中。
- 然后使用fmt.Println()函数打印这些变量。
- 循环结束后,使用rows.Err()检查迭代过程中的错误。如果有错误,我们使用log.Fatal(err)打印它。
错误处理和事务
在现实世界中,Go代码必须准备好处理错误和处理事务。SQL包提供了所有必要的工具:
func trans_insert() {// Error handling and transactionstx, 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)}
}
此代码开始事务,尝试执行插入语句,然后提交事务。如果在执行期间发生错误,它将回滚在该事务中所做的任何更改。
完整代码
package mainimport ("database/sql""fmt""log""time"_ "github.com/marcboeker/go-duckdb"
)var db *sql.DB
var err errorfunc main() {// Empty datasource means, that DB will be solely in-memory, otherwise you could specify a filename heredb, 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 transactionstx, 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 resultvar id intvar name stringvar startDt time.Timevar isRemote bool// Query single rowif 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 resultvar id intvar name stringvar startDt time.Timevar isRemote bool// Query multiple rowsrows, err := db.Query("SELECT id, name, start_dt, is_remote FROM employee")if err != nil {log.Fatal(err)}defer rows.Close()// Print the resultsfmt.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)}
}
最后总结
DuckDB对Go的支持允许开发人员直接从他们的Go应用程序中执行强大的数据分析操作。强大的数据管理系统和通用高效的编程语言之间的这种集成为更先进的数据处理应用打开了大门。有了本文提供的基础知识,你就可以开始探索这些可能性了。
相关文章:
DuckDB:Golang操作DuckDB实战案例
DuckDB是一个嵌入式SQL数据库引擎。它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的。DuckDB支持各种数据类型和SQL特性。凭借其在以内存为中心的环境中处理高速分析的能力,它迅速受到数据科学家和分析师的欢迎。在这篇博文中࿰…...
MySQL入门(数据库、数据表、数据、字段的操作以及查询相关sql语法)
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...
kotlin的协程的基础概念
Kotlin的协程是一种用于简化异步编程的强大工具。 理解协程的基础概念可以帮助开发者有效地利用其能力。 以下是Kotlin协程的一些关键基础概念: 协程(Coroutines) : 协程是一种用于处理并发任务的编程模型,它可以在单…...
Spring--SpringMVC使用(接收和响应数据、RESTFul风格设计、其他扩展)
SpringMVC使用 二.SpringMVC接收数据2.1访问路径设置2.2接收参数1.param和json2.param接收数据3 路径 参数接收4.json参数接收 2.3接收cookie数据2.4接收请求头数据2.5原生api获取2.6共享域对象 三.SringMVC响应数据3.1返回json数据ResponseBodyRestController 3.2返回静态资源…...
隐藏php版本信息x-powered-by
在生产环境中,并不想让别人知道用的是什么版本的php,可以把x-powered-by隐藏掉 在nginx配置文件加上fastcgi_hide_header X-Powered-By; 如下图所示 配置修改后平滑重启nginx...
哈夫曼树(构建、编码、译码)(详细分析+C++代码实现)
D 哈夫曼树 题目要求 编写一个哈夫曼编码译码程序。针对一段文本,根据文本中字符出现频率构造哈夫曼树,给出每个字符的哈夫曼编码,并进行译码,计算编码前后文本大小。 为确保构建的哈夫曼树唯一,本题做如下限定&…...
C++ 二叉搜索树
目录 概念 性能分析 二叉搜索树的插入 二叉树的查找 二叉树的前序遍历 二叉搜索树的删除(重点) 完整代码 key与value的使用 概念 对于一个二叉搜索树 若它的左子树不为空,则左子树上所有的节点的值都小于等于根节点的值若它的右子树不为空…...
docker构建Java项目镜像常用的Java版本,国内私有仓库公网快速下载,解决从docker.io无法下载的问题
2015工作至今,10年资深全栈工程师,CTO,擅长带团队、攻克各种技术难题、研发各类软件产品,我的代码态度:代码虐我千百遍,我待代码如初恋,我的工作态度:极致,责任ÿ…...
低代码系统-氚云、简道云表单控件对比
组件对比 氚云 简道云 是否都有 1 单行文本 单行文本 ☑️ 2 多行文本 多行文本 ☑️ 3 日期 日期时间 ☑️ 4 数字 数字 ☑️ 5 单选框 单选按钮组 ☑️ 6 复选框 复选框组 ☑️ 7 下拉框 下拉框 ☑️ 8 附件 附件 ☑️ 9 图片 图片 ☑️ 10 地址 地…...
为什么IDEA提示不推荐@Autowired❓️如果使用@Resource呢❓️
前言 在使用 Spring 框架时,依赖注入(DI)是一个非常重要的概念。通过注解,我们可以方便地将类的实例注入到其他类中,提升开发效率。Autowired又是被大家最为熟知的方式,但很多开发者在使用 IntelliJ IDEA …...
Unity在WebGL中拍照和录视频
原工程地址https://github.com/eangulee/UnityWebGLRecoder Unity版本2018.3.6f1,有点年久失修了 https://github.com/xue-fei/Unity.WebGLRecorder 修改jslib适配了Unity2021 效果图 录制的视频 Unity在WebGL中拍照和录视频...
爬虫基础之爬取某站视频
目标网址:为了1/4螺口买小米SU7,开了一个月,它值吗?_哔哩哔哩_bilibili 本案例所使用到的模块 requests (发送HTTP请求)subprocess(执行系统命令)re (正则表达式操作)json (处理JSON数据) 需求分析: 视频的名称 F12 打开开发者工具 or 右击…...
mongoDB常见指令
即使我们自己开发用不到mongoDB,但是接手别人项目的时候,别人如果用了,我们也要会简单调试一下 虽然mongoDB用的不是sql语句,但语句的逻辑都是相似的,比如查看数据库、数据表,增删改查这些 我们下面以doc…...
人工智能之深度学习_[5]-神经网络优化学习率衰减优化正则化方法
文章目录 神经网络入门二3 神经网络优化方法3.1 梯度下降算法回顾3.2 反向传播(BP算法)3.2.1 反向传播概念3.2.2 反向传播详解 3.3 梯度下降优化方法3.3.1 指数加权平均3.3.2 动量算法Momentum3.3.3 AdaGrad3.3.4 RMSProp3.3.5 Adam3.3.6 小结 4 学习率衰…...
Oracle之Merge into函数使用
Merge into函数为Oracle 9i添加的语法,用来合并update和insert语句。所以也经常用于update语句的查询优化: 一、语法格式: merge into A using B on (A.a B.a) --注意on后面带括号,且不能更新join的字段 when matched then upd…...
深度解析:哪种心磁图技术是心脏检查的精准之选?
在全球心血管疾病的阴影日益笼罩的今天,医学界正积极寻求一种无损、无创、无辐射的心脏健康监测方式。心磁图仪(MCG),这一前沿技术,凭借其独特的优势,悄然成为心脏电磁功能监测的新星。它不仅为心肌缺血、心…...
SpringBoot--基本使用(配置、整合SpringMVC、Druid、Mybatis、基础特性)
这里写目录标题 一.介绍1.为什么依赖不需要写版本?2.启动器(Starter)是何方神圣?3.SpringBootApplication注解的功效?4.启动源码5.如何学好SpringBoot 二.SpringBoot3配置文件2.1属性配置文件使用2.2 YAML配置文件使用2.3 YAML配置文件使用2.…...
单片机-STM32 IIC通信(OLED屏幕)(十一)
一、屏幕的分类 1、LED屏幕: 由无数个发光的LED灯珠按照一定的顺序排列而成,当需要显示内容的时候,点亮相关的LED灯即可,市场占有率很高,主要是用于户外,广告屏幕,成本低。 LED屏是一种用发光…...
观察者模式 - 观察者模式的应用场景
引言 观察者模式(Observer Pattern)是设计模式中行为型模式的一种,它定义了对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。观察者模式广泛应用于事件处理系统…...
【C++】详细讲解继承(下)
本篇来继续说说继承。上篇可移步至【C】详细讲解继承(上) 1.继承与友元 友元关系不能继承 ,也就是说基类友元不能访问派⽣类私有和保护成员。 class Student;//前置声明class Same //基类 { public:friend void Fun(const Same& p, con…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
