有什么 golang 下不依赖 cgo 的嵌入式 sql 数据库推荐吗?

2020-03-25 20:30:22 +08:00
 gamexg

如题,

sqlite 依赖于 cgo,不太方便交叉编译。

sqlite+dll 的方式只适合 windows,不适合 linux 。

kv 数据库有不少,但是功能上不如 sql 数据库齐全。

除此之外还有其他的选择吗?

储存少量数据需求,几千行数据。

5995 次点击
所在节点    Go 编程语言
21 条回复
janxin
2020-03-25 20:56:38 +08:00
搜索 sqlite pure golang
lniwn
2020-03-25 21:09:08 +08:00
前些天从 sqlite 换到了 kv 数据库 bolt,目前没有发现不适。
https://github.com/etcd-io/bbolt
Trim21
2020-03-25 21:11:44 +08:00
https://github.com/go-sqlite/sqlite3 “pure-Go sqlite3 file reader”
wsy2220
2020-03-25 21:22:42 +08:00
sqlite 是交叉编译最容易的 c 库了……
loading
2020-03-25 22:05:21 +08:00
golang 的交叉编译太简单了,除非还有别的库。
sqlite 真的香。
gamexg
2020-03-25 22:41:40 +08:00
@janxin #1 我搜索到的都是半成品,请问指的是?

@lniwn #2 我也是打算用 kv,不过有的地方需要自己实现索引有点麻烦,所以看看是否有更好的选择。

@Trim21 #3 只读?

@wsy2220 #4 但是维护各个平台下能够交叉编译到多环境挺麻烦。cgo 也碰到过多次奇怪的错误,想尽量避免 cgo 。

@loading #5 目前比较方便的交叉编译方式是? xgo ?
的确 sqlite 省心。
gamexg
2020-03-25 23:04:10 +08:00
@lniwn #2

我原来测试过 github.com/boltdb/bolt
批量写入时,如果 key 不是顺序而是随机值,第一次写入速度会非常慢,100000 条需要 19s 。
刚刚试了下,etcd 也存在这个问题。
yrj
2020-03-26 07:31:12 +08:00
楼主找到了也告诉我一声,我只找到了 sqlite
lniwn
2020-03-26 09:40:33 +08:00
@gamexg #7 方便把测试代码发出来看下吗?这种单文件数据库,每次 update 操作都是存盘的,用 batch 方式,或者手动事务应该不至于这么低的性能。
gamexg
2020-03-26 10:41:28 +08:00
@lniwn #9

```
package main

import (
"encoding/binary"
"fmt"
"log"
"math/rand"
"os"
"time"

"go.etcd.io/bbolt"
)

func itob(v int) []byte {
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(v))
return b
}

func main() {
test2()
}

// 测试随机批量连续
func test2() {
os.Remove("test2.db")
db, err := bbolt.Open("test2.db", 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()

err = db.Update(func(tx *bbolt.Tx) error {
_, err := tx.CreateBucketIfNotExists([]byte("MyBucket"))
return err
})
if err != nil {
panic(err)
}

buf := []byte("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")

data := make([]int, 100000)
for i, _ := range data {
data[i] = rand.Int()
}

for i := 0; i < 20; i++ {
sTime := time.Now()
err = db.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket([]byte("MyBucket"))
for _, v := range data {
err := b.Put(itob(v), buf)
if err != nil {
return err
}
}
return nil
})
/*
乱序批量写 100000:15.2067849s
乱序批量写 100000:409.6209ms
乱序批量写 100000:421.3134ms
乱序批量写 100000:381.5371ms
乱序批量写 100000:381.5839ms
乱序批量写 100000:361.8394ms
乱序批量写 100000:362.8142ms
乱序批量写 100000:364.7673ms
乱序批量写 100000:359.8283ms
乱序批量写 100000:376.0383ms
乱序批量写 100000:361.9876ms
乱序批量写 100000:362.0323ms
乱序批量写 100000:374.0311ms
乱序批量写 100000:365.0348ms
乱序批量写 100000:360.0383ms
乱序批量写 100000:361.022ms
乱序批量写 100000:364.0195ms
乱序批量写 100000:354.024ms
乱序批量写 100000:370.0098ms
乱序批量写 100000:379.9845ms
*/
fmt.Println("乱序批量写 100000:", time.Now().Sub(sTime))
}
}

```
ysmood
2020-03-26 13:34:23 +08:00
lniwn
2020-03-26 16:16:45 +08:00
@gamexg #10 我用 Begin/Commit 试了下,第一次也是耗时很久。
bwangel
2020-03-30 14:36:46 +08:00
楼主是否考虑带服务端的嵌入式数据库?

https://github.com/taosdata/TDengine

https://github.com/rqlite/rqlite

这两个的客户端都是纯 Go,就是需要额外启动一个服务端,但服务端的存储都是单文件,看起来没那么复杂。
bwangel
2020-03-30 14:52:30 +08:00
还有一个

https://gitlab.com/cznic/ql

看到 2020 年还在更新。
monkeyWie
2020-04-01 16:05:16 +08:00
推荐两个 K/V 库
https://github.com/xujiajun/nutsdb
https://github.com/prologic/bitcask
如果习惯写 sql 的话还是建议 sqlite,用 xgo 交叉编译就行了,参考: https://monkeywie.github.io/2019/10/10/go-cross-compile
wzw
2020-05-11 09:30:17 +08:00
@monkeyWie #15 刚接触 Go. 所以想问问 为啥是推荐这 2 个数据库

而不是
badger - Fast key-value store in Go.
bbolt - An embedded key/value database for Go.
monkeyWie
2020-05-12 16:46:04 +08:00
wzw
2020-05-12 17:01:32 +08:00
@monkeyWie #17 key 不变, value 变化, 重复写, 数据库会变很大, 不会自动清理空间...
wzw
2020-05-13 15:10:35 +08:00
@monkeyWie #17 我最后选了 badger, 然后自己看着 redis/ssdb 的 api 文档, 封装了一下
monkeyWie
2020-05-13 15:32:44 +08:00
@wzw 好吧,我之前看 badger K,V 都是[]byte 类型,就没太想用了🤣

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/656175

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX