第三节 boltdb的简单用法
其实boltdb的用法很简单,从其项目github的文档里面就可以看得出来。它本身的定位是key/value(后面简称为kv)存储的嵌入式数据库,因此那提到kv我们自然而然能想到的最常用的操作,就是set(k,v)和get(k)了。确实如此boltdb也就是这么简单。
不过在详细介绍boltdb使用之前,我们先以日常生活中的一些场景来作为切入点,引入一些在boltdb中抽象出来的专属名词(DB、Bucket、Cursor、k/v等),下面将进入正文,前面提到boltdb的使用确实很简单,就是set和get。但它还在此基础上还做了一些额外封装。下面通过现实生活对比来介绍这些概念。
boltdb本质就是存放数据的,那这和现实生活中的柜子就有点类似了,如果我们把boltdb看做是一个存放东西的柜子的话,它里面可以存放各种各样的东西,确实是的,但是我们想一想,所有东西都放在一起会不会有什么问题呢?
咦,如果我们把钢笔、铅笔、外套、毛衣、短袖、餐具这些都放在一个柜子里的话,会有啥问题呢?这对于哪些特别喜欢收拾屋子,东西归类放置的人而言,简直就是一个不可容忍的事情,因为所有的东西都存放在一起,当东西多了以后就会显得杂乱无章。
在生活中我们都有分类、归类的习惯,例如对功能类似的东西(钢笔、铅笔、圆珠笔等)放一起,或者同类型的东西(短袖、长袖等)放一起。把前面的柜子通过隔板来隔开,分为几个小的小柜子,第一个柜子可以放置衣服,第二个柜子可以放置书籍和笔等。当然了,这是很久以前的做法了,现在买的柜子,厂家都已经将其内部通过不同的存放东西的规格做好了分隔。大家也就不用为这些琐事操心了。既然这样,那把分类、归类这个概念往计算机中迁移过来,尤其是对于存放数据的数据库boltdb中,它也需要有分类、归类的思想,因为归根到底,它也是由人创造出来的嘛。
好了到这儿,我们引入我们的三大名词了“DB”、“Bucket”、“k/v”。
DB: 对应我们上面的柜子。
Bucket: 对应我们将柜子分隔后的小柜子或者抽屉了。
k/v: 对应我们放在抽屉里的每一件东西。为了方便我们后面使用的时候便捷,我们需要给每个东西都打上一个标记,这个标记是可以区分每件东西的,例如k可以是该物品的颜色、或者价格、或者购买日期等,v就对应具体的东西啦。这样当我们后面想用的时候,就很容易找到。尤其是女同胞们的衣服和包包,哈哈
再此我们就可以得到一个大概的层次结构,一个柜子(DB)里面可以有多个小柜子(Bucket),每个小柜子里面存放的就是每个东西(k/v)啦。
那我们想一下,我们周末买了一件新衣服,回到家,我们要把衣服放在柜子里,那这时候需要怎么操作呢?
很简单啦,下面看看我们平常怎么做的。
第一步:如果家里没有柜子,那就得先买一个柜子;
第二步:在柜子里找找之前有没有放置衣服的小柜子,没有的话,那就分一块出来,总不能把新衣服和钢笔放在一块吧。
第三步:有了放衣服的柜子,那就里面找找,如果之前都没衣服,直接把衣服打上标签,然后丢进去就ok啦;如果之前有衣服,那我们就需要考虑要怎么放了,随便放还是按照一定的规则来放。这里我猜大部分人还是会和我一样吧。喜欢按照一定的规则放,比如按照衣服的新旧来摆放,或者按照衣服的颜色来摆放,或者按照季节来摆放,或者按照价格来摆放。哈哈
我们在多想一下,周一早上起来我们要找一件衣服穿着去上班,那这时候我们又该怎么操作呢?
第一步:去找家里存放东西的柜子,家里没柜子,那就连衣服都没了,尴尬…。所以我们肯定是有柜子的,对不对
第二步:找到柜子了,然后再去找放置衣服的小柜子,因为衣服在小柜子存放着。
第三步:找到衣服的柜子了,那就从里面找一件衣服了,找哪件呢!最新买的?最喜欢的?天气下雨了,穿厚一点的?天气升温了,穿薄一点的?今天没准可能要约会,穿最有气质的?…..
那这时候根据不同场景来确定了规则,明确了我们要找的衣服的标签,找起来就会很快了。我们一下子就能定位到要穿的衣服了。嗯哼,这就是排序、索引的威力了
如果之前放置的衣服没有按照这些规则来摆放。那这时候就很悲剧了,就得挨个挨个找,然后自己选了。哈哈,有点全表扫描的味道了
啰里啰嗦扯了一大堆,就是为了给大家科普清楚,一些boltdb中比较重要的概念,让大家对比理解。降低理解难度。下面开始介绍boltdb是如何简单使用的。
使用无外乎两个操作:set、get
import "bolt"
func main(){
// 我们的大柜子
db, err := bolt.Open("./my.db", 0600, nil)
if err != nil {
panic(err)
}
defer db.Close()
// 往db里面插入数据
err = db.Update(func(tx *bolt.Tx) error {
//我们的小柜子
bucket, err := tx.CreateBucketIfNotExists([]byte("user"))
if err != nil {
log.Fatalf("CreateBucketIfNotExists err:%s", err.Error())
return err
}
//放入东西
if err = bucket.Put([]byte("hello"), []byte("world")); err != nil {
log.Fatalf("bucket Put err:%s", err.Error())
return err
}
return nil
})
if err != nil {
log.Fatalf("db.Update err:%s", err.Error())
}
// 从db里面读取数据
err = db.View(func(tx *bolt.Tx) error {
//找到柜子
bucket := tx.Bucket([]byte("user"))
//找东西
val := bucket.Get([]byte("hello"))
log.Printf("the get val:%s", val)
val = bucket.Get([]byte("hello2"))
log.Printf("the get val2:%s", val)
return nil
})
if err != nil {
log.Fatalf("db.View err:%s", err.Error())
}
}