Boltdb学习笔记之〇--概述
文章目录
更多精彩内容,请关注微信公众号:后端技术小屋
看了boltdb也有一阵子了,看完之后总想写点什么,因为感觉到这可能是个不小的坑,所以迟迟没有动笔(没错我的拖延症又犯了..)。最近有一种流行的说法:如果一个东西不能把它讲清楚,便不能说你学会了它。因为看起来会和真的会之间有一个巨大的鸿沟,想跨越这个鸿沟便需要不断的提问、思考与输出,这是个相对枯燥但绝对值得的过程,因此趁着周末两天的完整时间正式开始挖坑。
什么是boltdb
Boltdb是一个go语言开发的嵌入式kv数据库。其实现相对简单:
- 不支持网络请求和SQL查询,因此也就没有了网络交互、词法分析、语法分析、查询优化等成熟数据库中必不可少的功能。
- 使用了比较少见的shadow page技术,只支持一个writer和多个reader,在这种约束下,事务的隔离级别为可串行话,并发控制也比较简单
- 使用mmap将内存与磁盘建立映射,由OS管理磁盘page load到内存的过程,大大减少了boltdb手动管理的复杂度。
Boltdb所有代码加起来才1W行,但是麻雀虽小五脏俱全,非常适合用来学习数据库中的一些基本原理和概念,例如page、transanction、cursor等。
值得一提的是,Boltdb还是etcd底层的kv存储,目前Boltdb原仓库(https://github.com/boltdb/bolt)已经是read-only状态。而etcd维护了一个fork(https://github.com/etcd-io/bbolt), 主要是为了继续增强可靠性、稳定性和性能。
如何使用boltdb
数据模型
在使用boltdb之前,我们需要对其数据模型有个直观的了解。以下是boltdb与关系型数据库的数据模型简单类比:
boltdb中的概念 | 关系型数据库中的概念 |
---|---|
DB | database |
Bucket | table |
key value pair | Tuple |
Boltdb中的Bucket虽然可简单类比成关系型数据中table,有一点却不相同:前者可嵌套创建Bucket, 即一个Bucket下还可创建子Bucket, 而后者不行。
安装
|
|
操作DB
操作DB包括创建(打开)、关闭。
代码如下:在执行bolt.Open
时,如果指定文件路径不存在,则根据路径创建一个数据库文件;否则加载该路径下的文件。使用db.Close
便可关闭DB.
|
|
操作事务
Boltdb中按照是否只读将事务分为读事务和写事务。
用户使用db.View
创建读事务时需传入一个回调函数,表示读事务执行操作。如果回调函数返回的err != nil
,db.View
则会回滚该事务,并将err
透传给db.View
|
|
使用db.Update
可创建写事务。db.Update
如何处理错误同db.View
|
|
操作Bucket
操作Bucket包括创建Bucket、删除Bucket
创建Bucket属于写事务。这里db.Update
会创建一个写事务,写事务执行的操作是CreateBucket
,即创建一个新的Bucket
|
|
删除Bucket也属于写事务。使用上同理
|
|
操作key/value
操作key/value包括:新建/更新/删除/查询。所有的key/value对都必须属于某个具体的Bucket. 因此操作key/value之前必须找到Bucket对象。
新建/更新代码必须用写事务封装,代码如下,这里在名为MyBucket
的Bucket下新增了一对("answer", "42")
|
|
删除代码如下:
|
|
查询代码如下:
|
|
如何分析Boltdb
代码导读
首先是读代码,从微观到宏观的层面了解这座房屋如何建成的。代码阅读顺序是
|
|
更详细的代码细节将在该系列的后续内容中给出.
分析工具
Boltdb提供了一个好用的工具,可用于查看db file中每个page的内容
安装:
|
|
查看所有pages状态
|
|
其中ID表示page id, TYPE为page类型,ITEMS表示其中的数据条数,OVRFLW表示该page是否溢出。
查看某个page的内容
|
|
以上为某个leaf page的内容,底部为该page中存储的key/value对。
推荐阅读
- 一文读懂clickhouse集群监控
- redis实现分布式锁
- C/C++关键字之restrict
- 现代C++之右值语义
- 30分钟入门Vim
- 30分钟入门GDB
- STL源码分析–vector
- zookeeper client原理总结
- 推荐几个好用的效率神器
- Python乱码九问
- Linux Shell脚本攻略读书笔记
文章作者 后端侠
上次更新 2021-03-07