UnQLite是一个嵌入式NoSQL(键/值存储和文档存储)数据库引擎。不同于其他绝大多数NoSQL数据库,UnQLite没有一个独立的服务器进程。UnQLite直接读/写普通的磁盘文件。包含多个数据集的一个完整的数据库,存储在单一的磁盘文件中。数据库文件格式是跨平台的,可以在32位和64位系统或大端和小端架构之间,自由拷贝一个数据库。UnQLite的主要特点。
详情参考:http://unqlite.github.io/2013/05/26/about/
unqlite安装与配置:
这个我就不多说了,直接上shell脚本。
以下是ubuntu安装shell脚本
<!-- lang: shell -->
#! /bin/sh
# 下载源码
wget -c http://unqlite.org/db/unqlite-db-116.zip
# 解压源码
unzip unqlite-db-116.zip
# 编译源码
gcc -Wall -fPIC -c *.c
gcc -shared -Wl,-soname,libunqlite.so.1 -o libunqlite.so.1.0 *.o
# 建立软链接
sudo cp `pwd`/libunqlite.so.1.0 /usr/local/lib/
sudo cp `pwd`/unqlite.h /usr/local/include/
sudo ln -sf /usr/local/lib/libunqlite.so.1.0 /usr/local/lib/libunqlite.so.1
sudo ln -sf /usr/local/lib/libunqlite.so.1 /usr/local/lib/libunqlite.so
# 建立共享
sudo ldconfig /usr/local/lib/libunqlite.so
# 下载golang unqlite驱动包
git clone git@github.com:ceh/gounqlite.git
使用google go语言测试unqlite数据库
以下是测试代码:
<!-- lang: cpp -->
package main
import (
"bytes"
"fmt"
"github.com/ceh/gounqlite"
"sync"
"time"
)
var (
db *gounqlite.Handle
mutex sync.Mutex
)
func init() {
mutex.Lock()
defer mutex.Unlock()
if db != nil {
return
}
// 如果open定义为":mem:"字符,数据存储在内存中;
// 指定路径文件,数据会存储在文件中。
udb, err := gounqlite.Open(":mem:")
if err != nil {
fmt.Println("Open: ", err.Error())
return
}
db = udb
}
// 测试数据
var kvs = []struct {
key []byte
value []byte
}{
{[]byte("name"), []byte("viney")},
{[]byte("国家"), []byte("中国")},
{[]byte("email"), []byte("viney.chow@gmail.com")},
}
// 性能测试
func benchmark() {
count := 1000
finish := make(chan bool)
t := time.Now()
for i := 0; i < count; i++ {
go func(i int) {
defer func() { finish <- true }()
byt := []byte(fmt.Sprint(i))
if err := db.Store(byt, byt); err != nil {
fmt.Println("benchmark: ", err.Error())
return
}
}(i)
}
for i := 0; i < count; i++ {
<-finish
}
fmt.Println(time.Now().Sub(t).String())
}
func main() {
// 性能测试
benchmark()
// 添加数据/修改数据
// 如果key有数据会修改数据, 否则添加数据
for _, v := range kvs {
// 添加数据
if err := db.Store(v.key, v.value); err != nil {
fmt.Println("insert: ", err.Error(), string(v.key), string(v.value))
return
}
// 查询
if value, err := db.Fetch(v.key); err != nil {
fmt.Println("Fetch: ", err.Error())
return
} else if !bytes.Equal(v.value, value) {
fmt.Println("Equal: ", string(v.value), string(value))
return
}
// 修改数据
var hello []byte = []byte("hello")
if err := db.Store(v.key, hello); err != nil {
fmt.Println("update: ", err.Error())
return
}
// 查询修改之后的数据
if value, err := db.Fetch(v.key); err != nil {
fmt.Println("Fetch: ", err.Error())
return
} else if !bytes.Equal(hello, value) {
fmt.Println("Equal: ", string(hello), string(value))
return
}
// 追加数据
var world []byte = []byte("world")
if err := db.Append(v.key, world); err != nil {
fmt.Println("Append: ", err.Error())
return
}
// 查询追加之后的数据
if value, err := db.Fetch(v.key); err != nil {
fmt.Println("Fetch: ", err.Error())
return
} else if value != nil {
hello = append(hello, world...)
if !bytes.Equal(value, hello) {
fmt.Println("Equal: ", string(value), string(hello))
return
}
}
// 删除
if err := db.Delete(v.key); err != nil {
fmt.Println("Delete: ", err.Error())
return
}
}
// 关闭open
defer func() {
if err := db.Close(); err != nil {
fmt.Println("Close: ", err.Error())
return
}
}()
}
转载请注明出处.
写博客的目的:记录,升华,量变到质变