Случаи, когда стоит отказаться от idb-keyval в пользу idb

idb-keyval — это лёгкая библиотека-обёртка над IndexedDB, предназначенная для упрощения работы с ключ–значение. Она обеспечивает простую и лаконичную API, сводящую операции с базой данных к get, set, delete, clear и keys. Несмотря на удобство и минимализм, её возможности ограничены по сравнению с полной библиотекой idb.

Основные ограничения idb-keyval:

  • Отсутствие поддержки сложных запросов и индексов. Все операции выполняются по ключу, нет возможности фильтровать данные по значениям или создавать вторичные индексы.
  • Отсутствие транзакций с несколькими объектными хранилищами. Если необходимо атомарно обновлять несколько хранилищ одновременно, idb-keyval не подходит.
  • Нет контроля версий базы данных. При необходимости обновлять схему, добавлять новые хранилища или управлять миграциями, библиотека ограничивает гибкость.
  • Ограниченные возможности работы с большими объёмами данных. Для сложных структур и больших массивов объектов производительность может быть ниже, чем при прямой работе с idb.

Сценарии, когда idb-keyval недостаточна

1. Работа с несколькими объектными хранилищами

В idb можно создавать и управлять несколькими объектными хранилищами (object stores), устанавливать их ключи, индексы и стратегии хранения. idb-keyval же поддерживает только одно хранилище по умолчанию, что делает невозможным хранение логически разделённых наборов данных без дополнительной обёртки.

Пример использования idb для двух хранилищ:

import { openDB } from 'idb';

const db = await openDB('my-database', 1, {
  upgrade(db) {
    db.createObjectStore('users', { keyPath: 'id' });
    db.createObjectStore('orders', { keyPath: 'orderId' });
  },
});

idb-keyval такой гибкости не предоставляет, и попытка разделить данные приведёт к необходимости создавать несколько инстансов с разными именами, что усложняет управление.

2. Сложные транзакции

idb позволяет создавать транзакции, которые охватывают несколько хранилищ, гарантируя атомарность операций:

const tx = db.transaction(['users', 'orders'], 'readwrite');
await tx.objectStore('users').put({ id: 1, name: 'Alice' });
await tx.objectStore('orders').put({ orderId: 101, userId: 1 });
await tx.done;

В idb-keyval каждая операция выполняется отдельно. Если одна из операций не выполнится, отката всей группы изменений не произойдёт.

3. Индексы и поиск по значениям

Для быстрого поиска по определённым полям объекта idb позволяет создавать индексы:

const store = db.transaction('users').objectStore('users');
store.createIndex('byName', 'name');
const usersNamedAlice = await store.index('byName').getAll('Alice');

В idb-keyval поиск возможен только по ключу. Любая фильтрация по значениям потребует загрузки всех данных и фильтрации в памяти, что неэффективно при больших объёмах.

4. Управление версиями и миграции

idb предоставляет возможность обновления схемы базы данных, добавления новых хранилищ, изменения индексов и миграций данных при изменении версии базы:

const db = await openDB('my-database', 2, {
  upgrade(db, oldVersion) {
    if (oldVersion < 2) {
      db.createObjectStore('products', { keyPath: 'id' });
    }
  },
});

idb-keyval не поддерживает версионирование, поэтому изменение структуры базы потребует ручного удаления и пересоздания данных, что может привести к потере информации.

5. Масштабируемые приложения

Для приложений, где объём данных растёт, а требования к консистентности и скорости выборки высоки, прямое использование idb обеспечивает:

  • Множественные индексы для быстрых запросов.
  • Контроль транзакций и их атомарность.
  • Эффективное хранение и выборку больших массивов объектов.

idb-keyval остаётся удобным инструментом для небольших проектов, быстрых прототипов или хранения пользовательских настроек, но при масштабировании его возможностей часто не хватает.

Вывод по выбору библиотеки

idb-keyval оправдан, когда требуется минималистичный интерфейс для хранения отдельных значений и простых структур. В случае:

  • необходимости работы с несколькими объектными хранилищами,
  • использования транзакций и атомарных операций,
  • поиска по значениям и индексации,
  • управления схемой базы и миграций,

целесообразно отказаться от idb-keyval и использовать idb, обеспечивающий полноценный контроль над IndexedDB.