GoLang BoltDB数据库详解
raoxiaoya 人气:0说明
Bolt是一个纯粹Key/Value
模型的程序。该项目的目标是为不需要完整数据库服务器(如Postgres或MySQL)的项目提供一个简单,快速,可靠的数据库。
BoltDB只需要将其链接到你的应用程序代码中即可使用BoltDB提供的API来高效的存取数据。而且BoltDB支持完全可序列化的ACID事务,让应用程序可以更简单的处理复杂操作。
BoltDB设计源于LMDB,具有以下特点:
- 使用Go语言编写
- 不需要服务器即可运行
- 支持数据结构
- 直接使用API存取数据,没有查询语句
- 支持完全可序列化的ACID事务,这个特性比LevelDB强
- 数据保存在内存映射的文件里。没有wal、线程压缩和垃圾回收
- 通过COW技术,可实现无锁的读写并发,但是无法实现无锁的写写并发,这就注定了读性能超高,但写性能一般,适合与读多写少的场景
BoltDB是一个Key/Value
(键/值)存储,这意味着没有像SQL RDBMS(MySQL,PostgreSQL等)
中的表,没有行,没有列。相反,数据作为键值对存储(如在Golang Maps中)。键值对存储在Buckets中,它们旨在对相似的对进行分组(这与RDBMS中的表类似)。因此,为了获得Value(值),需要知道该Value所在的桶和钥匙。
go get -u github.com/boltdb/bolt
打开数据库
db, err := bolt.Open(dbfile, 0600, nil) if err != nil { log.Fatal(err) } defer db.Close()
更新事务
err := db.Update(func(tx *bolt.Tx) error { ... return nil })
说明:
- 通过该接口可以实现数据更新操作该操作
- 会被当做一个事务来处理,如果Update()内的操作返回nil,则事务会被提交,否则事务会回滚
只读操作
err := db.View(func(tx *bolt.Tx) error { ... return nil })
说明:
通过该接口可以且只能进行数据查询操作 批量更新事务
err := db.Batch(func(tx *bolt.Tx) error { ... return nil })
说明:
- 通过该接口可以实现多次数据更新操作
- 所有的更新会被当做一个事务来处理,如果Update()内的操作返回nil,则事务会被提交,否则事务会回滚
手动事务管理
// Start a writable transaction. tx, err := db.Begin(true) if err != nil { return err } defer tx.Rollback() // Use the transaction... _, err := tx.CreateBucket([]byte("MyBucket")) if err != nil { return err } // Commit the transaction and check for error. if err := tx.Commit(); err != nil { return err }
说明:
自己创建事务,并管理事务的提交和回滚,没有利用BoltDB提供的封装式写法 示例
package main import ( "fmt" "log" "github.com/boltdb/bolt" ) var dbfile = "boltdbfile.db" var bdb *bolt.DB var bucket = []byte("MyBuckets") func main() { var err error bdb, err = bolt.Open(dbfile, 0600, nil) if err != nil { log.Fatal(err) } defer func() { _ = bdb.Close() }() CreateBuckets() updateData() selectData() } func CreateBuckets() error { return bdb.Update(func(tx *bolt.Tx) error { _, err := tx.CreateBucketIfNotExists(bucket) return err }) } func updateData() error { return bdb.Update(func(tx *bolt.Tx) error { bk := tx.Bucket(bucket) if bk != nil { e1 := bk.Put([]byte("name"), []byte("rao")) if e1 != nil { return e1 } e2 := bk.Put([]byte("age"), []byte("12")) if e2 != nil { return e2 } } return nil }) } func selectData() error { var name, age []byte return bdb.View(func(tx *bolt.Tx) error { bk := tx.Bucket(bucket) if bk != nil { name = bk.Get([]byte("name")) age = bk.Get([]byte("age")) } fmt.Printf("%s\n", name) fmt.Printf("%s\n", age) return nil }) }
加载全部内容