go-memdb

基于不可改变的 radix 树的 Golang 内存数据库。「Golang in-memory database built on immutable radix trees」

  • 所有者: hashicorp/go-memdb
  • 平台: Linux, Mac, Windows
  • 許可證: Mozilla Public License 2.0
  • 分類:
  • 主題:
  • 喜歡:
    0
      比較:

Github星跟蹤圖

go-memdb

提供 memdb 包,它实现了一个建立在不可改变的 radix 树上的简单内存数据库。该数据库提供原子性、一致性和与 ACID 隔离。由于是内存数据库,它不提供耐久性。数据库被实例化时有一个模式,该模式指定了存在的表和索引,并允许执行事务。

数据库提供了以下功能:

  • 多版本并发控制(MVCC)-- 通过利用不可变的 radix 树,数据库能够支持任何数量的并发读取器,而不需要锁定,并允许写入器取得进展。
  • 事务支持 -- 数据库允许丰富的事务,其中插入、更新或删除多个对象。事务可以跨越多个表,并以原子方式应用。数据库在ACID术语中提供了原子性和隔离性,因此在提交之前,更新是不可见的。
  • 丰富的索引 -- 表可以支持任意数量的索引,可以是简单的如单字段索引,也可以是更高级的复合字段索引。某些类型,如UUID,可以有效地从字符串压缩成字节索引,以减少存储需求。
  • 监视 -- 调用者可以填充一个监视集作为查询的一部分,它可以用来检测何时对数据库进行了影响查询结果的修改。这让调用者可以很容易地以一种非常通用的方式观察数据库的变化。

关于底层的不可改变的 radix 树,请参见 go-immutable-radix

文档

完整的文档可以在 Godoc 上找到。

例子

下面是一个简单的使用实例

// Create a sample struct
type Person struct {
    Email string
    Name  string
    Age   int
}

// Create the DB schema
schema := &memdb.DBSchema{
    Tables: map[string]*memdb.TableSchema{
        "person": &memdb.TableSchema{
            Name: "person",
            Indexes: map[string]*memdb.IndexSchema{
                "id": &memdb.IndexSchema{
                    Name:    "id",
                    Unique:  true,
                    Indexer: &memdb.StringFieldIndex{Field: "Email"},
                },
                "age": &memdb.IndexSchema{
                    Name:    "age",
                    Unique:  false,
                    Indexer: &memdb.IntFieldIndex{Field: "Age"},
                },
            },
        },
    },
}

// Create a new data base
db, err := memdb.NewMemDB(schema)
if err != nil {
    panic(err)
}

// Create a write transaction
txn := db.Txn(true)

// Insert some people
people := []*Person{
    &Person{"joe@aol.com", "Joe", 30},
    &Person{"lucy@aol.com", "Lucy", 35},
    &Person{"tariq@aol.com", "Tariq", 21},
    &Person{"dorothy@aol.com", "Dorothy", 53},
}
for _, p := range people {
    if err := txn.Insert("person", p); err != nil {
        panic(err)
    }
}

// Commit the transaction
txn.Commit()

// Create read-only transaction
txn = db.Txn(false)
defer txn.Abort()

// Lookup by email
raw, err := txn.First("person", "id", "joe@aol.com")
if err != nil {
    panic(err)
}

// Say hi!
fmt.Printf("Hello %s!\n", raw.(*Person).Name)

// List all the people
it, err := txn.Get("person", "id")
if err != nil {
    panic(err)
}

fmt.Println("All the people:")
for obj := it.Next(); obj != nil; obj = it.Next() {
    p := obj.(*Person)
    fmt.Printf("  %s\n", p.Name)
}

// Range scan over people with ages between 25 and 35 inclusive
it, err = txn.LowerBound("person", "age", 25)
if err != nil {
    panic(err)
}

fmt.Println("People aged 25 - 35:")
for obj := it.Next(); obj != nil; obj = it.Next() {
    p := obj.(*Person)
    if p.Age > 35 {
        break
    }
    fmt.Printf("  %s is aged %d\n", p.Name, p.Age)
}
// Output:
// Hello Joe!
// All the people:
//   Dorothy
//   Joe
//   Lucy
//   Tariq
// People aged 25 - 35:
//   Joe is aged 30
//   Lucy is aged 35


主要指標

概覽
名稱與所有者hashicorp/go-memdb
主編程語言Go
編程語言Go (語言數: 1)
平台Linux, Mac, Windows
許可證Mozilla Public License 2.0
所有者活动
創建於2015-06-16 22:54:29
推送於2025-04-16 09:58:47
最后一次提交
發布數16
最新版本名稱v1.3.5 (發布於 )
第一版名稱v1.0.0 (發布於 )
用户参与
星數3.3k
關注者數337
派生數215
提交數169
已啟用問題?
問題數59
打開的問題數34
拉請求數65
打開的拉請求數12
關閉的拉請求數35
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?

go-memdb CircleCI

Provides the memdb package that implements a simple in-memory database
built on immutable radix trees. The database provides Atomicity, Consistency
and Isolation from ACID. Being that it is in-memory, it does not provide durability.
The database is instantiated with a schema that specifies the tables and indices
that exist and allows transactions to be executed.

The database provides the following:

  • Multi-Version Concurrency Control (MVCC) - By leveraging immutable radix trees
    the database is able to support any number of concurrent readers without locking,
    and allows a writer to make progress.

  • Transaction Support - The database allows for rich transactions, in which multiple
    objects are inserted, updated or deleted. The transactions can span multiple tables,
    and are applied atomically. The database provides atomicity and isolation in ACID
    terminology, such that until commit the updates are not visible.

  • Rich Indexing - Tables can support any number of indexes, which can be simple like
    a single field index, or more advanced compound field indexes. Certain types like
    UUID can be efficiently compressed from strings into byte indexes for reduced
    storage requirements.

  • Watches - Callers can populate a watch set as part of a query, which can be used to
    detect when a modification has been made to the database which affects the query
    results. This lets callers easily watch for changes in the database in a very general
    way.

For the underlying immutable radix trees, see go-immutable-radix.

Documentation

The full documentation is available on Godoc.

Example

Below is a simple example of usage

// Create a sample struct
type Person struct {
	Email string
	Name  string
	Age   int
}

// Create the DB schema
schema := &memdb.DBSchema{
	Tables: map[string]*memdb.TableSchema{
		"person": &memdb.TableSchema{
			Name: "person",
			Indexes: map[string]*memdb.IndexSchema{
				"id": &memdb.IndexSchema{
					Name:    "id",
					Unique:  true,
					Indexer: &memdb.StringFieldIndex{Field: "Email"},
				},
				"age": &memdb.IndexSchema{
					Name:    "age",
					Unique:  false,
					Indexer: &memdb.IntFieldIndex{Field: "Age"},
				},
			},
		},
	},
}

// Create a new data base
db, err := memdb.NewMemDB(schema)
if err != nil {
	panic(err)
}

// Create a write transaction
txn := db.Txn(true)

// Insert some people
people := []*Person{
	&Person{"joe@aol.com", "Joe", 30},
	&Person{"lucy@aol.com", "Lucy", 35},
	&Person{"tariq@aol.com", "Tariq", 21},
	&Person{"dorothy@aol.com", "Dorothy", 53},
}
for _, p := range people {
	if err := txn.Insert("person", p); err != nil {
		panic(err)
	}
}

// Commit the transaction
txn.Commit()

// Create read-only transaction
txn = db.Txn(false)
defer txn.Abort()

// Lookup by email
raw, err := txn.First("person", "id", "joe@aol.com")
if err != nil {
	panic(err)
}

// Say hi!
fmt.Printf("Hello %s!\n", raw.(*Person).Name)

// List all the people
it, err := txn.Get("person", "id")
if err != nil {
	panic(err)
}

fmt.Println("All the people:")
for obj := it.Next(); obj != nil; obj = it.Next() {
	p := obj.(*Person)
	fmt.Printf("  %s\n", p.Name)
}

// Range scan over people with ages between 25 and 35 inclusive
it, err = txn.LowerBound("person", "age", 25)
if err != nil {
	panic(err)
}

fmt.Println("People aged 25 - 35:")
for obj := it.Next(); obj != nil; obj = it.Next() {
	p := obj.(*Person)
	if p.Age > 35 {
		break
	}
	fmt.Printf("  %s is aged %d\n", p.Name, p.Age)
}
// Output:
// Hello Joe!
// All the people:
//   Dorothy
//   Joe
//   Lucy
//   Tariq
// People aged 25 - 35:
//   Joe is aged 30
//   Lucy is aged 35