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万条记录来计时上面的方法,看看它是怎么做的呢?我肯定要在这方面做一个基准测试。我只是有点惊讶,没有一个用于该用例的库。但我想在磁盘上存储结构树是很常见的。