“This is the 18th day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021.”

Today’s talk: BoltDB database, a pure Go KV database

This article appears in my column: Blockchain in Detail

This column will describe the blockchain consensus algorithm, ethereum smart contract, super ledger smart contract, EOS smart contract related knowledge, and also introduce several practical projects in detail. If possible, we can also read the source code of Ethereum together. If you are interested, let’s learn block chain technology together

What is BoltDB

This is a key/value database written purely in Go, which is said to reference the open source memory mapping database LMDB. Notably, the database does not support network connectivity, nor does it support complex SQL statement queries. However, it can be more convenient to achieve data persistence in the application of Go.

Two, use scenarios

  1. Go language prepared procedures, this procedure needs embedded database.
  2. No complex SQL statement queries are required.
  3. The database is better at reading, so it works better when there are more reads and fewer writes.

Three, installation and use method

The installation method is very simple, is the command line execution:

go get github.com/boltdb/bolt/...
Copy the code

So how do we open the database? Let’s take a look at the following code.

package main import ( "log" "github.com/boltdb/bolt" ) func main() { // Open the my.db data file in your current directory. // It will be created if it doesn't exist. db, err := bolt.Open("my.db", 0600, nil) if err ! = nil { log.Fatal(err) } defer db.Close() ... }Copy the code

This bolt.open () opens the database on the given path. If the database file you want to open does not exist, it will be created automatically. The second parameter is file mode. The third argument is passed nil and Bolt opens the database using the default options.

Bolt cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until another process closes it. To prevent an indefinite wait, we need to give the Open() function a timeout argument:

db, err := bolt.Open("my.db", 0600, &bolt.Options{Timeout: 1 * time.Second})
Copy the code

The transaction

Bolt supports only one read-write transaction at a time, but can support multiple read-only transactions at a time.

The transaction API for reading and writing is Update, and the second transaction API for reading is View.

err := db.Update(func(tx *bolt.Tx) error {
    ...
    return nil
})
​
Copy the code
err := db.View(func(tx *bolt.Tx) error {
    ...
    return nil
})
​
Copy the code

Note: Read-only and read-write transactions should not normally open in the same Goroutine at the same time. This can lead to deadlocks because read/write transactions need to periodically remap data files, but cannot do so when a read-only transaction is open.

There is also a Batch transaction that reduces the overhead of concurrent write operations. Batch is only useful if it is called by multiple Goroutines.

err := db.Batch(func(tx *bolt.Tx) error {
    ...
    return nil
})
​
Copy the code

Read and write operations

db.Update(func(tx *bolt.Tx) error {
    b := tx.Bucket([]byte("MyBucket"))
    err := b.Put([]byte("answer"), []byte("42"))
    return err
})
​
Copy the code

This is to write data to the database with the key answer value 42.

db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("MyBucket")) v := b.Get([]byte("answer")) fmt.Printf("The answer  is: %s\n", v) return nil })Copy the code

This is the data read with key answer.

Bucket() : tx Bucket() : tx Bucket() : tx Bucket()

One interesting thing about Bolt is the Bucket. This is the basic way the database organizes data. For example, there is a Bucket called a company, and inside this Bucket there is a Bucket called a department, which contains a key: ReganYue, this means that ReganYue is a person in the department, but also a person in the company. The key belongs to the Bucket of the department and the Bucket of the company.