Overwrite/Throw Go LevelDB 中的重复键错误

Overwrite/Throw error on duplicate key in Go LevelDB

当使用下面的代码时,我希望数据库中只有一个条目。 我使用 Go 的 syndtr/goleveldb LevelDB 实现。

for count := 0; count < 5; count++ {
    err := db.Put([]byte("key"), []byte("value"))
    if err != nil {
        t.Error(err)
    }
}

相反,hexdump 显示有 5 个条目:

00000000  a8 ef d2 d4 17 00 01 01  00 00 00 00 00 00 00 01  |................|
00000010  00 00 00 01 03 6b 65 79  05 76 61 6c 75 65 10 23  |.....key.value.#|
00000020  44 b5 17 00 01 02 00 00  00 00 00 00 00 01 00 00  |D...............|
00000030  00 01 03 6b 65 79 05 76  61 6c 75 65 77 be 34 95  |...key.valuew.4.|
00000040  17 00 01 03 00 00 00 00  00 00 00 01 00 00 00 01  |................|
00000050  03 6b 65 79 05 76 61 6c  75 65 08 35 86 60 17 00  |.key.value.5.`..|
00000060  01 04 00 00 00 00 00 00  00 01 00 00 00 01 03 6b  |...............k|
00000070  65 79 05 76 61 6c 75 65  6f 8c f6 00 17 00 01 05  |ey.valueo.......|
00000080  00 00 00 00 00 00 00 01  00 00 00 01 03 6b 65 79  |.............key|
00000090  05 76 61 6c 75 65                                 |.value|
00000096

根据我的理解 LevelDB 应该默认覆盖任何重复的键或者至少抛出一个错误。

我如何控制该值何时被覆盖或如何出现错误(除了每次 db.Put(key) 时检查 db.Has(key)compaction与此有什么关系吗?

LevelDB 是一个 log-structured merge-tree 并且具有事务日志(您使用 hexdump 检查的那些)。使用此代码,您可以验证您的键是否只存在一个值:

package main

import ( "fmt"
"github.com/syndtr/goleveldb/leveldb"
)

func main () {
        db, err := leveldb.OpenFile("mydb.test", nil)
        if err != nil { fmt.Println(err) }

        for count := 0; count < 5; count++ {
                err := db.Put([]byte("keys"), []byte("values"), nil)
                if err != nil {
                    fmt.Println(err)
                }
        }

        iter := db.NewIterator(nil, nil)
        for iter.Next() {
                key := iter.Key()
                value := iter.Value()
                fmt.Println(string(key), string(value))
        }
        iter.Release()

        defer db.Close()
}

How can I control when the value gets overwritten?

你不能,如果密钥存在,它的值会被覆盖