亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 gob 序列化到磁盤后檢索

使用 gob 序列化到磁盤后檢索

Go
POPMUISE 2022-12-05 11:18:42
我一直在學習數據庫,并希望出于學習目的而非生產目的實施一個數據庫。我有一個定義的模式: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.decodefunc 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以最簡單和慣用的方式模仿這種行為?
查看完整描述

1 回答

?
阿晨1998

TA貢獻2037條經驗 獲得超6個贊

一個 Gob 流可能包含類型定義和解碼指令,所以你不能尋找一個 Gob 流。您只能從頭開始閱讀,直到找到所需內容為止。

Gob 流完全不適合需要跳過元素的數據庫存儲格式。

您可以創建一個新的編碼器并分別序列化每個記錄,在這種情況下您可以跳過元素(通過維護一個文件索引來存儲哪個記錄從哪個位置開始),但這將是非常低效和冗余的(如鏈接答案中所述,當您寫入更多相同類型的值時,速度和存儲成本會攤銷,并且總是創建新的編碼器會失去這種收益)。

更好的方法是不encoding/gob為此使用,而是定義自己的格式。為了有效地支持搜索(select),您必須在可搜索的列/字段上構建某種索引,否則您仍然需要執行全表掃描。


查看完整回答
反對 回復 2022-12-05
  • 1 回答
  • 0 關注
  • 102 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號