V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
gamexg
V2EX  ›  Go 编程语言

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

  •  1
     
  •   gamexg ·
    gamexg · 2020-03-25 20:30:22 +08:00 · 5925 次点击
    这是一个创建于 1498 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,

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

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

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

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

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

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

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

    @Trim21 #3 只读?

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

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

    我原来测试过 github.com/boltdb/bolt
    批量写入时,如果 key 不是顺序而是随机值,第一次写入速度会非常慢,100000 条需要 19s 。
    刚刚试了下,etcd 也存在这个问题。
    yrj
        8
    yrj  
       2020-03-26 07:31:12 +08:00 via iPad
    楼主找到了也告诉我一声,我只找到了 sqlite
    lniwn
        9
    lniwn  
       2020-03-26 09:40:33 +08:00
    @gamexg #7 方便把测试代码发出来看下吗?这种单文件数据库,每次 update 操作都是存盘的,用 batch 方式,或者手动事务应该不至于这么低的性能。
    gamexg
        10
    gamexg  
    OP
       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
        11
    ysmood  
       2020-03-26 13:34:23 +08:00
    lniwn
        12
    lniwn  
       2020-03-26 16:16:45 +08:00
    @gamexg #10 我用 Begin/Commit 试了下,第一次也是耗时很久。
    bwangel
        13
    bwangel  
       2020-03-30 14:36:46 +08:00
    楼主是否考虑带服务端的嵌入式数据库?

    https://github.com/taosdata/TDengine

    https://github.com/rqlite/rqlite

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

    https://gitlab.com/cznic/ql

    看到 2020 年还在更新。
    monkeyWie
        15
    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
        16
    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
        17
    monkeyWie  
       2020-05-12 16:46:04 +08:00
    wzw
        18
    wzw  
       2020-05-12 17:01:32 +08:00
    @monkeyWie #17 key 不变, value 变化, 重复写, 数据库会变很大, 不会自动清理空间...
    wzw
        19
    wzw  
       2020-05-13 15:10:35 +08:00
    @monkeyWie #17 我最后选了 badger, 然后自己看着 redis/ssdb 的 api 文档, 封装了一下
    monkeyWie
        20
    monkeyWie  
       2020-05-13 15:32:44 +08:00
    @wzw 好吧,我之前看 badger K,V 都是[]byte 类型,就没太想用了🤣
    wzw
        21
    wzw  
       2020-05-13 15:35:43 +08:00
    @monkeyWie #20 用 goframe 的 gconv 超级好用.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2446 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 13:44 · PVG 21:44 · LAX 06:44 · JFK 09:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.