Go 在磁盘上存储结构树

Go 在磁盘上存储结构树,go,struct,Go,Struct,我有以下结构: type Post struct { Id int Name string Text string Posts []Post } 要添加一些数据,我将执行以下操作: var posts []Post posts = append(posts, Post{Id: 0, Name: "a", Text: "b"}) posts[0].Posts = append(posts[0].Posts, Post{Id: 1, Name: "c", Text: "

我有以下结构:

type Post struct {
  Id    int
  Name  string
  Text  string
  Posts []Post
}
要添加一些数据,我将执行以下操作:

var posts []Post

posts = append(posts, Post{Id: 0, Name: "a", Text: "b"})
posts[0].Posts = append(posts[0].Posts, Post{Id: 1, Name: "c", Text: "d"})

posts = append(posts, Post{Id: 2, Name: "e", Text: "f"})
posts[0].Posts = append(posts[0].Posts, Post{Id: 3, Name: "h", Text: "d"})
如何在磁盘上高效地存储此结构树?我正在寻找一些不需要服务器就可以使用的东西(比如SQLite)。我希望能够搜索
Id
2或3,分别返回带有
Id
2或3的整个结构。此外,我希望能够更新单个结构,例如Id为
2的结构


另外,使用映射,使用
Id
作为映射的键是否更好?

使用编码/gob将二进制数据放入文件或再次取出

import (
    "bufio"
    "encoding/gob"
    "fmt"
    "os"
)

type Post struct {
    Id    int
    Name  string
    Text  string
    Posts []Post
}

func main() {

    var posts []Post

    posts = append(posts, Post{Id: 0, Name: "a", Text: "b"})
    posts[0].Posts = append(posts[0].Posts, Post{Id: 1, Name: "c", Text: "d"})

    posts = append(posts, Post{Id: 2, Name: "e", Text: "f"})
    posts[0].Posts = append(posts[0].Posts, Post{Id: 3, Name: "h", Text: "d"})
    fmt.Printf("%v\n", posts)

    path := "post.gob"

    // write
    out, err1 := os.Create(path)
    if err1 != nil {
        fmt.Printf("File write error: %v\n", err1)
        os.Exit(1)
    }
    w := bufio.NewWriter(out)
    enc := gob.NewEncoder(w)
    enc.Encode(posts)
    w.Flush()
    out.Close()

    // read
    b := make([]Post, 10)
    in, err2 := os.Open(path)
    if err2 != nil {
        fmt.Printf("File read error: %v\n", err2)
        os.Exit(1)
    }
    r := bufio.NewReader(in)
    dec := gob.NewDecoder(r)
    dec.Decode(&b)

    fmt.Printf("%v\n", b)

}

建议的解决方案可能取决于问题中未提及的因素,例如,您打算存储多少个结构,它们是否可以读入内存,字符串长度和树的深度是否有任何限制?@icza这些因素与我的用例并不相关,但我希望有一个高效的解决方案,它可以存储10个,但也可以存储10万个结构。字符串可以限制(1024个字符),但应该是可配置的。这同样适用于树的深度,在我的用例中,最大深度为10是一个很好的例子。@icza经过一些思考后,我注意到,根据这些因素,看看存在什么类型的不同解决方案是很有趣的。当您需要一个没有数据库服务器的数据库时,SQLite是一个很好的选择。这可能是对一组记录进行原子更新的最简单方法。如果您不想手工编写SQL,也可以使用Gorm关系管理器。谢谢您的回答。不幸的是,这样我只能获取/更新
帖子的全部内容,而不能获取/更新单个结构。您可以更新单个结构。但您必须加载所有这些文件,进行更新,然后重新编写它们。例如,如果将每个Post结构放在一个文件中,那么更新可能会快一点,但读取速度会慢一点。有一些折中的方法,比如使用切分(将Post struct列表拆分为一半或四分之一)。然而,所有这些听起来都像是在重塑数据库。为什么不试着用10万条记录来计时上面的方法,看看它是怎么做的呢?我肯定要在这方面做一个基准测试。我只是有点惊讶,没有一个用于该用例的库。但我想在磁盘上存储结构树是很常见的。