1. ホーム
  2. スクリプト・コラム
  3. ゴラン

Golangの高性能な永続化ソリューションBoltDB Databaseの紹介

2022-01-06 07:38:42

1. ボルトの紹介

BoltDBは、インメモリ・マップド・ファイルにデータを保存する永続化ソリューションの純粋なGo言語による実装です。データベースではなく永続化ソリューションと呼ばれるのは、データベースという言葉にはボルトが持っていない多くの機能が追加されているからです。このような機能がないからこそ、boltはとてもエレガントで使い勝手が良いのです。

BoltはGoのパッケージです。システムにインストールする必要はなく、コーディングを始める前に設定する必要もなく、ただただ go get github.com/boltdb/bolt そして import "github.com/boltdb/bolt" .

boltのストレージ機能をフルに使うには、ファイル名さえあればいいのです。これは開発者の視点からもユーザーの視点からも信じられないことだと感じています。私の経験では、PostgreSqlやOracle、NoSQLなどのリレーショナルデータベースでは、データベース環境の構築、設定の問題、ユーザーやパーミッションのデバッグ、その他様々な問題に多くの時間を費やしました。これはアプリケーションを使う側にとってもありがたいことで、面倒なことに頭を悩ませる必要がありません。

Boltはリレーショナルデータベースではありません。そのような使い方はできますが、ドキュメントを保存することもありません。ただ、キーと値のペアを保存するだけです。でも、その意味がわからなくても、どうやって保存に使うのかわからなくても、心配しないでください。超シンプルで非常にフレキシブルなので、見てみましょう。

2. 例

バケットは名前とキー、そして[]byte型の値を持っています。バケットには他のバケットを含めることができ、キーとして[]byte型の名前を渡すこともできます。

...以上です。boltは基本的にネストしたマッピングの集合です。このシンプルさが使いやすさにつながっています。設定するテーブルもスキーマも複雑なクエリ言語もありません。boltのスターターの例を見てみましょう。

package main
import (
	"fmt"
	"github.com/boltdb/bolt"
	"log"
)
var world = []byte("greeting")
func main() {
	db, err := bolt.Open("d:/bolt.db", 0644, nil)
	if err ! = nil {
		log.Fatal(err)
	}
	defer db.Close()
	key := []byte("hello")
	value := []byte("Hello World!")
	// store some data
	err = db.Update(func(tx *bolt.Tx) error {
		bucket, err := tx.CreateBucketIfNotExists(world)
		if err ! = nil {
			return err
		}

		err = bucket.Put(key, value)
		if err ! = nil {
			return err
		}
		return nil
	})
	if err ! = nil {
		log.Fatal(err)
	}
	// retrieve the data
	err = db.View(func(tx *bolt.Tx) error {
		bucket := tx.
		if bucket == nil {
			return fmt.Errorf("Bucket %s not found!", world)
		}
		val := bucket.Get(key)
		fmt.Println(string(val))
		return nil
	})
	if err ! = nil {
		log.Fatal(err)
	}
}

出力します。 Hello World!

について考えていると思います。---このコードは少し長いようです。しかし、少なくとも半正規の方法で、すべてのエラーを完全に処理したことを思い出してください。

データベースを作成する

構造体の作成(挨拶のグループ化)

構造体にデータを格納する

構造体からデータを取得する

空行を含めても54行のコードで、それほど悪くはない。以下は、上記の例で実装されている内容を具体的に説明したものです。

3. 解析例

まず bolt.Open がデータベースに接続し、ファイルを作成するか、既存のファイルを開く必要がある場合。
ボルトの読み込みと書き込みの操作はすべてトランザクションの中で行わなければなりません。読み取り専用のトランザクションでは、同時に多くの読み取り操作を行うことができますが、書き込み操作は一度に1つだけです(書き込み側が書き込みを行っている間、読み取り側はデータベースの一貫したビューを維持します)。

を呼び出すだけです。 db.Update を引数にとり、関数自体は bolt.Tx ----bolt のトランザクションオブジェクトをとります。そして、バケットが作成され(boltの全てのデータはバケットで構成されています)、その後、キーと値のペアが追加されます。書き込みトランザクションが終了したら、読み取り操作を開始します ---- DB.Viewトランザクションを使用して、書き込んだばかりのデータを取得します。

ボルト・トランザクションの仕組みの強力な点は、関数のスコープがトランザクションのスコープになるという非常にシンプルな点です。もし関数にUpdateを渡してnilを返せば、トランザクション内の全ての更新操作がアトミックにライブラリに格納されます。もし関数がエラーを返した場合、トランザクションはロールバックされます。このため、Go開発者はボルト・トランザクションを非常に簡単に行うことができます。普通にエラーを返すだけで、関数を早期に終了させることができ、boltは正しい処理をします。手動で更新をロールバックするなどの心配は不要で、ただエラーを返せばいいのです。

もう1つの基本的な操作として、Bucket内のキーと値のペアを繰り返し処理する必要があるかもしれません。この場合、カーソル値を返すBucket.Cursor()を呼び出すだけで、キーと値のペアを返して期待通りに動くNext(), Prev(), などの関数を持っています。

bolt APIには他にもたくさんありますが、残りのほとんどはデータベースの統計や、より高度な使用シナリオのコンテンツについてです ...... しかし、boltデータベースにデータを保存し始めるには、上記が本当に知っておくべきことです。

4. 概要

より複雑なアプリケーションでは、データベースに文字列を保存するだけでは不十分かもしれませんが、大丈夫です。Goのエンコーディング関連パッケージが役に立ちます。encoding/jsonやencoding/gobを使って、一意名やidをキーにした構造をデータベースに簡単にシリアライズすることができます。繰り返しになりますが、ボルトの利点は使用する際の障壁が低いことです。データベーススキーマ全体を把握したり、高性能で管理しやすい方法でデータをディスクに保存するために何かをインストールしたりする必要がありません。

ボルトの主な欠点は、クエリーがないことです。barで始まる全てのfooオブジェクトをください、とは言えないのです。データベースに独自のインデックスを作り、それを手動で更新することができます。IDのスライス(slice)を特定のクエリのための「インデックス」バケットにシリアライズするのと同じくらい簡単です。明らかにこのあたりから独自のリレーショナル・データベースの開発を始めるべきですが、無理をしないのであれば、このコードだけで十分でしょう。外部DSLにあるこれらのクエリは、インメモリデータストレージのためのコードに過ぎないのです。

ボルトはすべての用途に使えるわけではありません。アプリケーションのニーズと、そのニーズを満たすのにボルトのキー/バリューのスタイルで十分かどうかを理解する必要があります。そうであれば、脳のオーバーヘッドがあまりないシンプルなデータストレージを使うのがとても幸せになれると思います。

以上、Golangの高性能永続化ソリューションBoltDBデータベース紹介の詳細でしたが、Golang永続化BoltDBの詳細については、BinaryDevelopの他の関連記事にも注目してください