- Bolt 是一个纯粹的 Go key/value数据库。 该项目的目标是为不需要完整数据库服务器(如Postgres或MySQL)的项目提供一个简单,快速和可靠的数据库。
- 如果您需要高随机写入吞吐量(> 10,000 w / sec)或者您需要使用旋转磁盘,则 LevelDB可能是一个不错的选择。 如果你的应用程序是重读的,或者做了很多范围扫描,Bolt 可能是一个不错的选择。
- Bolt 适合读取密集型工作负载。顺序写入性能也很快,但随机写入可能会很慢。
安装
go get github.com/boltdb/bolt/...
案例
package main
import (
"github.com/boltdb/bolt"
"fmt"
"os"
)
func main() {
//打开数据库
//Bolt中的顶??级对象是一个DB。它被表示为磁盘上的单个文件,表示数据的一致快照。
//Bolt 会在数据文件上获得一个文件锁,所以多个进程不能同时打开同一个数据库。
// 打开一个已经打开的 Bolt 数据库将导致它挂起,直到另一个进程关闭它。为防止无限期等待,您可以将超时选项传递给Open()函数:
//db,err := bolt.Open("test.db", 0600, &bolt.Options{Timeout: 1 * time.Second})
db, err := bolt.Open("test.db", 0600, nil)
if err != nil {
fmt.Println("bolt.Open failed:", err)
os.Exit(1)
}
defer db.Close()
//读写事务
//在闭包内部,您有一个一致的数据库视图。 您通过返回零来完成交易。 您也可以通过返回错误来随时回滚事务。
//每个 DB.Update() 等待磁盘提交写入。通过将多个更新与 DB.Batch() 函数结合,可以最小化这种开销
db.Update(func(tx *bolt.Tx) error {
//buckets存储区是数据库中 key/value 对的集合。 bucket 中的所有 key 必须是唯一的。
bucket := tx.Bucket([]byte("firstBucket")) //获取bucket
if bucket == nil {
//使用 Tx.CreateBucketIfNotExists() 函数不存在的情况下,可以创建一个 bucket 。
//要删除一个 bucket,只需调用 Tx.DeleteBucket() 函数即可。
bucket, err = tx.CreateBucket([]byte("firstBucket")) //创建一个存储 bucket
if err != nil {
fmt.Println("createBucket failed:", err)
os.Exit(1)
}
}
//写数据
bucket.Put([]byte("aaa"), []byte("hellworld"))
bucket.Put([]byte("bbb"), []byte("baibai"))
bucket.Put([]byte("ccc"), []byte("ququ"))
return nil
})
//只读事务
//您也可以在此闭包中获得数据库的一致视图,但是,在只读事务中不允许进行变异操作。您只能检索存储区,检索值,或者在只读事务中复制数据库。
db.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte("firstBucket"))
if bucket == nil {
fmt.Println("Bucket is nil!")
os.Exit(1)
}
//读数据
//使用 Bucket.Delete() 函数从 bucket 中删除一个 key。
value := bucket.Get([]byte("bbb"))
fmt.Println("bbb => ", string(value))
value = bucket.Get([]byte("ccc"))
fmt.Println("ccc => ", string(value))
return nil
})
//迭代keys
db.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte("firstBucket"))
cursor := bucket.Cursor() //遍历 key
for k, v := cursor.First(); k != nil; k, v = cursor.Next() {
fmt.Printf("key=%s, value=%s\n", k, v)
}
//也可以使用 ForEach() 函数
/*
bucket.ForEach(func(k, v []byte) error {
fmt.Printf("key=%s, value=%s\n", k, v)
return nil
})
*/
return nil
})
}