Что может содержать `Bucket` в key-value хранилищах, таких как BoltDB?

Ответ

В key-value хранилищах, реализующих модель Bucket (например, BoltDB или bbolt), ключ внутри одного Bucket может указывать на одно из двух:

  1. Значение (value) — это просто срез байт ([]byte).
  2. Вложенный Bucket (nested bucket) — это, по сути, дочерняя таблица с собственным набором ключей и значений.

Ключевой момент заключается в том, что один и тот же ключ не может одновременно указывать и на значение, и на вложенный Bucket.

Пример проверки содержимого

Чтобы определить, что хранится по ключу, нужно последовательно проверить оба варианта. Сначала пытаемся получить значение с помощью .Get(). Если результат nil, это может быть либо несуществующий ключ, либо вложенный Bucket.

err := db.View(func(tx *bbolt.Tx) error {
    // Получаем родительский Bucket
    parentBucket := tx.Bucket([]byte("MyParentBucket"))
    if parentBucket == nil {
        return fmt.Errorf("parent bucket not found")
    }

    key := []byte("MyKey")

    // 1. Пытаемся получить значение
    val := parentBucket.Get(key)

    // 2. Если значения нет, проверяем, не является ли это вложенным Bucket'ом
    if val == nil {
        nestedBucket := parentBucket.Bucket(key)
        if nestedBucket != nil {
            fmt.Println("По ключу 'MyKey' находится вложенный Bucket.")
            // Здесь можно работать с nestedBucket
        } else {
            fmt.Println("Ключ 'MyKey' не найден.")
        }
    } else {
        fmt.Printf("По ключу 'MyKey' находится значение: %sn", val)
    }

    return nil
})