一架梯子,一头程序猿,仰望星空!

leveldb在golang中的基本用法


levelDB是Google开源的高性能的键值数据库, 而且leveldb是一种内嵌在程序中的数据库,我们可以把leveldb数据库嵌入到我们程序中。

leveldb特性:

  • key和value支持存储任意长度的字节数组
  • 数据存储根据key排序
  • 支持自定义排序规则
  • 支持批量原子操作
  • 支持遍历数据
  • 自动使用Snappy算法压缩数据

这里主要介绍在go语言中如何使用leveldb, 因为leveldb官方版本是c++版本,我们这里使用goleveldb,go语言版本的leveldb。

github地址: https://github.com/syndtr/goleveldb

1.安装包

go get github.com/syndtr/goleveldb/leveldb

2.go版本要求

大于1.5版本

3.创建或者打开数据库

// The returned DB instance is safe for concurrent use. Which mean that all
// DB's methods may be called concurrently from multiple goroutine.
// 通过OpenFile函数创建或者打开一个已经存在的数据库,文件名可以随意取。
// OpenFile函数返回的db实例支持并发调用,我们可以在多个协程并发环境中读写数据。
db, err := leveldb.OpenFile("./tizi365.db", nil)

// 延迟关闭数据库
defer db.Close()

4.根据key保存数据

// 因为leveldb的key和value都是byte数组类型
// 存储数据的时候根据自己数据类型转换下
// 这里key = tizi, value = www.tizi365.com
err = db.Put([]byte("tizi"), []byte("www.tizi365.com"), nil)

5.根据key读取数据

// 读取key = tizi的数据
// 注意:返回的数据也是byte数组,需要自己根据需要转换类型
data, err := db.Get([]byte("tizi"), nil)

// 注意不能修改返回的数据,如果想修改的建议复制一份字节数组到新的变量

6.删除数据

// 根据key删除数据
err = db.Delete([]byte("tizi"), nil)

7.遍历数据库

遍历整个数据库

// 创建迭代器实例
iter := db.NewIterator(nil, nil)
// 如果迭代器还有下一个内容,继续遍历
for iter.Next() {
	// 注意不能修改返回的数据,如果想修改的建议复制一份字节数组到新的变量
        // 读取key
	key := iter.Key()
        // 读取value
	value := iter.Value()
}
// 释放迭代器
iter.Release()
err = iter.Error()
...

也可以定位到某个key,然后从这个key的位置开始往后遍历

iter := db.NewIterator(nil, nil)
// 通过Seek函数定位到key = tizi的位置
for ok := iter.Seek([]byte("tizi")); ok; ok = iter.Next() {
	// 读取数据
}
iter.Release()
err = iter.Error()
...

遍历某个范围的数据

// 遍历key=foo作为开始位置,key=xoo作为结束位置之间的数据
iter := db.NewIterator(&util.Range{Start: []byte("foo"), Limit: []byte("xoo")}, nil)
for iter.Next() {
	// 读取数据
}
iter.Release()
err = iter.Error()
...

8.批量更新数据

// 初始化Batch实例,用来打包操作
batch := new(leveldb.Batch)
// 写数据
batch.Put([]byte("foo"), []byte("value"))
// 写数据
batch.Put([]byte("bar"), []byte("another value"))
// 删除key
batch.Delete([]byte("baz"))
// 调用Write函数,批量更新数据
err = db.Write(batch, nil)

9.判断key是否存在

if ok, _ := db.Has([]byte("tizi", nil); ok {
   // key = tizi 存在
}