Расскажите о своем опыте работы с типом данных JSON/JSONB в базах данных из Go.

Ответ

Да, я активно использовал тип jsonb в PostgreSQL для хранения слабоструктурированных данных.

В Go для работы с jsonb используется стандартный пакет database/sql в связке с драйвером (например, pgx или lib/pq).

Основные подходы:

  1. Сканирование в map[string]interface{} или []interface{}: Удобно для данных с неизвестной или динамической структурой.
  2. Сканирование в конкретную структуру Go: Лучший подход для данных с известной структурой. Позволяет использовать статическую типизацию.
  3. Использование json.RawMessage ([]byte): Позволяет отложить парсинг JSON, что может быть полезно для производительности, если данные нужно просто передать дальше без обработки.

Пример полного цикла (Запись и Чтение):

// Структура для наших данных
type UserMetadata struct {
    Visits    int      `json:"visits"`
    LastSeen  time.Time `json:"last_seen"`
    Tags      []string `json:"tags"`
}

// --- Запись данных в jsonb ---
metadata := UserMetadata{
    Visits:   10,
    LastSeen: time.Now(),
    Tags:     []string{"go", "backend"},
}

// Драйвер сам преобразует структуру в JSON
_, err := db.Exec(`INSERT INTO users (id, metadata) VALUES ($1, $2)`, 
    1, metadata)

// --- Чтение данных из jsonb ---
var resultMeta UserMetadata
err = db.QueryRow(`SELECT metadata FROM users WHERE id = $1`, 1).Scan(&resultMeta)
if err != nil {
    // Обработка ошибки
}
fmt.Printf("User has %d visits", resultMeta.Visits)

Ключевые моменты:

  • Индексация: Основное преимущество jsonb перед json (в PostgreSQL) — это возможность создавать GIN-индексы, что позволяет очень эффективно запрашивать данные по ключам или наличию элементов внутри JSON-документа.
  • Драйверы: Современные драйверы, такие как pgx, отлично справляются с автоматическим Marshal/Unmarshal структур в/из JSON при работе с БД.