我一直在學習數據庫,并希望出于學習目的而非生產目的實施一個數據庫。我有一個定義的模式: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
),您必須在可搜索的列/字段上構建某種索引,否則您仍然需要執行全表掃描。
- 1 回答
- 0 關注
- 102 瀏覽
添加回答
舉報
0/150
提交
取消