使用 gob 序列化到磁盘后检索
Retrieval after serialization to disk using gob
我一直在学习数据库,也想实现一个用于学习目的而不是用于生产。我有一个定义的模式:
type Row struct {
ID int32
Username string
Email string
}
现在,目前,我能够以仅附加的方式将这种类型的结构编码到文件中。
//Just to show i use a file for the encoding, it has missing details.
func NewEncoder(db *DB) *gob.Encoder{
return gob.NewEncoder(db.File)
}
func SerializeRow(r Row, encoder *gob.Encoder, db *DB) {
err := encoder.Encode(r)
if err != nil {
log.Println("encode error:", err)
}
}
现在,通过简单地使用 gob.decode
解码整个文件来模仿“select”语句相对容易
func DeserializeRow(decoder *gob.Decoder, db *DB){
var rows Row
db.File.Seek(0, 0)
err := decoder.Decode(&rows)
for err == nil {
if err != nil {
log.Println("decode error:", err)
}
fmt.Printf("%d %s %s\n", rows.ID, rows.Username, rows.Email)
err = decoder.Decode(&rows)
}
}
我当前的问题是,我希望能够根据 ID 检索特定行。我知道 sqlite
使用 4kb 分页,在某种意义上,序列化的行占据一个“页面”,即。 4KB 直到一个页面不能再容纳它们,然后创建另一个。我如何使用 gob
以最简单和惯用的方式模仿这种行为?
看过:I have seen this and
Gob 流可能包含类型定义和解码指令,因此您无法寻找 Gob 流。您只能从头开始阅读,直到找到所需内容为止。
Gob 流完全不适合table 需要跳过元素的数据库存储格式。
您可以创建一个新的编码器并分别序列化每个记录,在这种情况下您可以跳过元素(通过维护一个文件索引来存储哪个记录从哪个位置开始),但这会非常低效和冗余(如所述在 中,速度和存储成本会随着您写入更多相同类型的值而摊销,并且总是创建新的编码器会失去这种收益。
更好的方法是不使用 encoding/gob
,而是定义自己的格式。为了有效地支持搜索 (select
),您必须在可搜索的列/字段上构建某种索引,否则您仍然需要执行完整的 table 扫描。
我一直在学习数据库,也想实现一个用于学习目的而不是用于生产。我有一个定义的模式:
type Row struct {
ID int32
Username string
Email string
}
现在,目前,我能够以仅附加的方式将这种类型的结构编码到文件中。
//Just to show i use a file for the encoding, it has missing details.
func NewEncoder(db *DB) *gob.Encoder{
return gob.NewEncoder(db.File)
}
func SerializeRow(r Row, encoder *gob.Encoder, db *DB) {
err := encoder.Encode(r)
if err != nil {
log.Println("encode error:", err)
}
}
现在,通过简单地使用 gob.decode
func DeserializeRow(decoder *gob.Decoder, db *DB){
var rows Row
db.File.Seek(0, 0)
err := decoder.Decode(&rows)
for err == nil {
if err != nil {
log.Println("decode error:", err)
}
fmt.Printf("%d %s %s\n", rows.ID, rows.Username, rows.Email)
err = decoder.Decode(&rows)
}
}
我当前的问题是,我希望能够根据 ID 检索特定行。我知道 sqlite
使用 4kb 分页,在某种意义上,序列化的行占据一个“页面”,即。 4KB 直到一个页面不能再容纳它们,然后创建另一个。我如何使用 gob
以最简单和惯用的方式模仿这种行为?
看过:I have seen this and
Gob 流可能包含类型定义和解码指令,因此您无法寻找 Gob 流。您只能从头开始阅读,直到找到所需内容为止。
Gob 流完全不适合table 需要跳过元素的数据库存储格式。
您可以创建一个新的编码器并分别序列化每个记录,在这种情况下您可以跳过元素(通过维护一个文件索引来存储哪个记录从哪个位置开始),但这会非常低效和冗余(如所述在
更好的方法是不使用 encoding/gob
,而是定义自己的格式。为了有效地支持搜索 (select
),您必须在可搜索的列/字段上构建某种索引,否则您仍然需要执行完整的 table 扫描。