传送门: 柏链项目学院

什么是Bolt?

  Bolt是一个纯净的基于go语言编写的key-val数据库,该项目受到LMDB项目的启发,目标是提供一个不需要完整服务器的简单、快速、可靠的数据库。

  Bolt稳定,API固定,文件格式固定。全单元测试覆盖和随机黑盒测试用于确保数据库一致性和线程安全性。Bolt目前用于高负载生产环境,为1TB的数据库提供服务。Shopify和Heroku等许多公司每天都使用Bolt支持的服务。

  唯一不好的一点作者自认为没时间更新了,以下为作者原文:

Bolt的最初目标是提供一个简单的纯Go键/值存储,并且不会使具有无关功能的代码膨胀。为此,该项目取得了成功。但是,这个有限的范围也意味着项目已经完成。

维护开源数据库需要大量的时间和精力。对代码的更改可能会产生意想不到的,有时甚至是灾难性的影响,因此即使是简单的更改也需要数小时和数小时的仔细测试和验证。

不幸的是,我不再有时间或精力继续这项工作。Bolt处于稳定状态,并且已经成功使用了多年。因此,我认为将其置于当前状态是最谨慎的行动方式。

如果您有兴趣使用更具特色的Bolt版本,我建议您查看名为bbolt的CoreOS分支

Bolt使用介绍

安装手册使用参考

安装

go get github.com/boltdb/bolt

使用以及相关API

  本文不详细介绍具体API用法,而是结合使用,将相关的API进行具体介绍。
Bolt的组织结构是:db(数据库) -- bucket(桶)-- key/val(键值对)

  • Open 打开数据库

  Open函数可以获得一个db对象,db对象对应一个Close函数

db, err := bolt.Open("my.db", 0600, nil)if err != nil {log.Fatal(err)}defer db.Close()
  • Update 读写操作模式
    dbptr 为之前Open函数返回的数据库操作指针,或者可以理解为我们之前使用数据库进行操作的连接。

  CreateBucketIfNotExists 是创建一个bucket的函数,也可以直接使用CreateBucket,名字长的这个相对安全一点,如果存在就不创建了,否则将会报错!

Put函数就是设置key-val对的函数,设置的内容存放在对应的bucket当中。

func setData(key, val string) error {//以读写方式操作数据库dbptr.Update(func(tx *bolt.Tx) error {//创建水桶b, err := tx.CreateBucketIfNotExists([]byte(bucket))if err != nil {fmt.Println("failed to create bucket", err)return err}//设置key-val对return b.Put([]byte(key), []byte(val))})return nil
}
  • View 只读操作模式

此种模式不涉及到对数据的修改,只有读取数据部分,同样是需要找到相同的bucket,然后寻找对应的key值。

View就是以只读方式操作数据库。

Get函数可以获得bucket中的key值。

func getData(key string) string {data := []byte{}//以只读方式操作数据库dbptr.View(func(tx *bolt.Tx) error {b := tx.Bucket([]byte(bucket))data = b.Get([]byte(key))return nil})return string(data)
}
  • 事务的支持

  万万没想到的是,这么小的数据库还能支持事务。事务的特点就是一次执行的多个数据库操作,要么一起成功,要么一起失败!这个是关系型数据库的必备特点,当发生错误时一个rollback就可以恢复现场,避免出现垃圾数据。关于ACID的问题,我们本文不进行讨论。我们重点来说说如何使用API以实现事务。

Begin函数代表开启一个事务。

Rollback函数可以在出错时回滚事务。

Commit函数在事务执行没有问题之后,进行整体提交。

func transactionTest() {//开启一个事务tx, err := dbptr.Begin(true)if err != nil {fmt.Println("failed to ")}//函数退出时回滚defer tx.Rollback()//找到一个水桶b := tx.Bucket([]byte(bucket))//设置name对应的值是fuhongxueerr = b.Put([]byte("name"), []byte("fuhongxue"))return //在这里return是有很大区别的,此时不会执行后面的commit,而是执行rollbackif err != nil {fmt.Println("failed to put name", err)return}//执行到这里时提交事务tx.Commit()
}

完整测试代码如下:

package mainimport ("fmt""github.com/boltdb/bolt"
)var dbptr *bolt.DBconst bucket = "mybucket"func setData(key, val string) error {//以读写方式操作数据库dbptr.Update(func(tx *bolt.Tx) error {//创建水桶b, err := tx.CreateBucketIfNotExists([]byte(bucket))if err != nil {fmt.Println("failed to create bucket", err)return err}//设置key-val对return b.Put([]byte(key), []byte(val))})return nil
}func getData(key string) string {data := []byte{}//以只读方式操作数据库dbptr.View(func(tx *bolt.Tx) error {b := tx.Bucket([]byte(bucket))data = b.Get([]byte(key))return nil})return string(data)
}func transactionTest() {//开启一个事务tx, err := dbptr.Begin(true)if err != nil {fmt.Println("failed to ")}//函数退出时回滚defer tx.Rollback()//找到一个水桶b := tx.Bucket([]byte(bucket))//设置name对应的值是fuhongxueerr = b.Put([]byte("name"), []byte("fuhongxue"))return //在这里return是有很大区别的,此时不会执行后面的commit,而是执行rollbackif err != nil {fmt.Println("failed to put name", err)return}//设置name对应的值是fuhongxue2err = b.Put([]byte("name"), []byte("fuhongxue2"))if err != nil {fmt.Println("failed to put name", err)return}//执行到这里时提交事务tx.Commit()
}func main() {//打开数据库文件,这个文件用于存放数据库的数据db, err := bolt.Open("db.db", 0600, nil)if err != nil {fmt.Println("failed to open db file", err)return}dbptr = dbdefer dbptr.Close()setData("name", "yekai")transactionTest()fmt.Println(getData("name"))
}

大家猜一猜执行结果会如何呢?

yekaideMacBook-Pro:test yk$ go run db.go
yekai

  因为transactionTest中存在一个return,导致事务并没有被提交,所以val值就是yekai,仍然与setData后的结果相同。

把return注释之后再来尝试以下!

yekaideMacBook-Pro:test yk$ go run db.go
fuhongxue2

  代码编写到此位置,通过使用可以发现,Bolt使用确实非常便捷!为了更好的理解,我们总结一下Bolt的使用和结构,都在图里了!

转载于:https://www.cnblogs.com/tokenpai/p/10414597.html

这么小的key-val数据库居然也支持事务——与短跑名将同名的数据库Bolt相关推荐

  1. qt中mysql怎么支持事务_Qt踩坑之mysql数据库不支持事务操作?

    文章已更新,最新地址:https://www.fearlazy.com/index.php/post/145.html 现象: 在调试数据库操作时发现还没commit数据已经插入表中,执行rollba ...

  2. python编写数据库连接工具_详解使用Python写一个向数据库填充数据的小工具(推荐)...

    一. 背景 公司又要做一个新项目,是一个合作型项目,我们公司出web展示服务,合作伙伴线下提供展示数据. 而且本次项目是数据统计展示为主要功能,并没有研发对应的数据接入接口,所有展示数据源均来自数据库 ...

  3. 学python需要学数据库吗-python支持哪些数据库

    数据库分类 早期数据库模型有三种,分别为层次式数据库.网络式数据库和关系型数据库. 而在当今的互联网中,通常把数据库分为两类,即关系型数据库和非关系型数据库. 关系型数据库 关系型数据库是指采用了关系 ...

  4. 数据库内核杂谈 - 一小时实现一个基本功能的数据库

    我们摒弃直接介绍数据库内核各个模块的思路,而是从应用开发者的角度出发,来看实现一个数据库需要哪些基本功能,然后把这些功能细分成最小的模块再手把手一起实现. 对与应用开发者而言,一个数据库需要哪些必要的 ...

  5. 缓存与数据库的一致性:先操作缓存还是先操作数据库?

    数据缓存 在我们实际的业务场景中,一定有很多需要做数据缓存的场景,比如售卖商品的页面,包括了许多并发访问量很大的数据,它们可以称作是是"热点"数据,这些数据有一个特点,就是更新频率 ...

  6. 支持自动水平拆分的高性能分布式数据库TDSQL

    随着互联网应用的广泛普及,海量数据的存储和访问成为系统设计的瓶颈问题.对于大型的互联网应用,每天几十亿的PV无疑对数据库造成了相当高的负载.给系统的稳定性和扩展性造成了极大的问题.通过数据的切分来提高 ...

  7. mysql数据库开发经历_六年开发经验,整理Mysql数据库技巧笔记,全网最详细的笔记集合!...

    数据库 表 DML DQL 多表查询 内连接查询 外连接查询 子查询 将一条查询语句作为一张虚拟表 Mysql约束 主键约束 特点:主键约束默认包含非空和唯一两个功能. 一张表只能有一个主键. 主键一 ...

  8. python建立sqlite数据库_5分钟快速入门,用Python做SQLite数据库开发,附代码适合初学...

    1.它内置,无需安装,省了很多麻烦. 2.使用方便,无需复杂的连接配置,和打开本地文件一样简单. 3.转移方便,数据库就是一个文件,复制.转移.删除都能简单处理 4.轻量级应用中性能优于多数其它的数据 ...

  9. MySQL数据库的索引、事务和存储引擎

    目录 一.索引 1.1 索引的概念 1.2 索引的作用 1.3 创建索引的原则 1.4 索引的分类 1.5 索引的创建 1.5.1 普通索引 1.5.2 唯一索引 1.5.3 主键索引 1.5.4 组 ...

最新文章

  1. Difference between CGLIB JDK Dynamic Proxies
  2. Judge Simple(判断-简单)
  3. python背单词小程序_python背单词小程序
  4. C++从屏幕输入数字以空格分割,存入整型数组
  5. MySQL表中部分字段生成视图_MySQL学习笔记之视图
  6. 学习语文必须掌握的知识点思维导图
  7. 用学习逃避成长,听新知缓解焦虑
  8. reset.css(常用项目代码初始化)
  9. 京东2020双十二活动终于来啦,脚本助你领年终
  10. STM32 CM0+系列芯片的NRST模式之坑
  11. python井字棋游戏大作业实验报告_Part 1.2 - 实现一个井字棋游戏的gym环境
  12. 【vue3】关于ref、toRef、toRefs那些事
  13. 查看网站服务器版本,查看网站为TLS或SSL及其版本
  14. 开启编程世界的临门一脚
  15. 切图工具GraphicsMagick安装
  16. ora-00972标识符过长
  17. 系统引导管理 之 用GRUB(包括WINGRUB)命令行模式引导安装Linux
  18. 埙,感受太古遗音[Teaks]
  19. Happytime RTSP Pusher,命令行工具提供
  20. python爬虫(14)获取淘宝MM个人信息及照片(上)

热门文章

  1. python lambda 逻辑_Python之lambda表达式和内置函数
  2. php的优势和背景,CSS_CSS 多图片融合背景定位的应用于优缺点分析,1. 关键字, 例如: background-positio - phpStudy...
  3. mysql 1594_【MySQL】复制1594错误(从库relaylog损坏)
  4. nullable java_java-持久性@Column nullable = false可以插入null
  5. stn算子_在 Excel 中,公式都是以 ____________ 开始的,后面由操作数和运算符构成。...
  6. 苹果终端date命令_mac 终端 常用命令
  7. 安装itunes需要管理员身份_Windows 10 在microsoft store 微软商店里安装的itunes如何更改备份位置...
  8. Vivado如何计算关键路径的保持时间裕量?
  9. 高速串行总线设计基础(五)揭秘SERDES高速面纱之多相数据提取电路与线路编码方案
  10. 【FPGA】单端口RAM的设计(异步读、同步写)