Числовые ключи и их особенности

Библиотека Idb-keyval предоставляет упрощённый интерфейс для работы с IndexedDB, скрывая большую часть сложности нативного API. Одной из особенностей этой библиотеки является возможность использования ключей разных типов, включая строки, числа и даже объекты. Особое внимание заслуживают числовые ключи, так как они имеют специфические нюансы в хранении, индексировании и последовательности.


Особенности числовых ключей

  1. Типизация ключей В IndexedDB ключи могут быть любого примитивного типа: строки, числа, даты, массивы. Числовые ключи рассматриваются отдельно и могут использоваться для естественной сортировки по возрастанию или убыванию. При работе с Idb-keyval это важно учитывать, так как библиотека автоматически приводит ключи к правильному виду для IndexedDB, но не выполняет конвертацию строк в числа.

  2. Сортировка и последовательность Если ключи представлены числами, то записи в IndexedDB будут сортироваться арифметически, а не лексикографически. Например, ключи [1, 2, 10] будут храниться в том же порядке, что и перечислены, тогда как строковые ключи ['1', '2', '10'] сортируются как ['1', '10', '2']. Это напрямую влияет на методы keys(), entries() и любые операции с диапазонами.

  3. Диапазонные запросы Idb-keyval позволяет выполнять операции с диапазонами числовых ключей, используя методы get() и getMany(). В IndexedDB диапазоны задаются через IDBKeyRange, и для чисел возможны все стандартные виды диапазонов:

    • IDBKeyRange.lowerBound(5) — все ключи ≥ 5
    • IDBKeyRange.upperBound(10) — все ключи ≤ 10
    • IDBKeyRange.bound(3, 7) — ключи от 3 до 7 включительно
    • IDBKeyRange.only(4) — только ключ 4

    Idb-keyval упрощает работу с этими диапазонами, но важно понимать, что числовые ключи обрабатываются точно как числа, без автоматического приведения типов.


Использование числовых ключей в Idb-keyval

Простейшие операции

import { set, get, del } from 'idb-keyval';

// Добавление числового ключа
set(1, { name: 'Объект 1', value: 100 });
set(2, { name: 'Объект 2', value: 200 });

// Получение значения по числовому ключу
const item = await get(1);
console.log(item); // { name: 'Объект 1', value: 100 }

// Удаление элемента
await del(2);

В этом примере видно, что числовой ключ используется как есть, без кавычек. Любая попытка обратиться к ключу '1' (строкой) вернёт undefined, так как IndexedDB различает строки и числа.


Итерация по числовым ключам

Idb-keyval поддерживает методы keys(), values() и entries(). При работе с числовыми ключами результат возвращается в отсортированном по возрастанию порядке:

import { keys, entries } from 'idb-keyval';

await set(10, 'Десять');
await set(2, 'Два');
await set(30, 'Тридцать');

const allKeys = await keys(); // [1, 2, 10, 30]
const allEntries = await entries();
/*
[
  [1, {...}],
  [2, 'Два'],
  [10, 'Десять'],
  [30, 'Тридцать']
]
*/

Такое поведение особенно полезно для числовых индексов, таймстампов или порядковых номеров.


Ограничения и тонкости

  1. Нет автоматического приведения типов Строка '1' и число 1 — это два разных ключа. Попытка использовать числовой ключ как строку приведёт к отсутствию совпадения.

  2. Работа с отрицательными числами Числовые ключи могут быть отрицательными. Они сохраняются и сортируются корректно, как обычные числа. Пример: [-10, -5, 0, 5, 10].

  3. Дробные значения IndexedDB и Idb-keyval поддерживают ключи с плавающей точкой. Важно помнить, что точность чисел с плавающей запятой может влиять на поиск и сравнение, особенно при диапазонных запросах.

  4. Смешанные типы ключей Если в одном хранилище присутствуют и числовые, и строковые ключи, их сортировка будет выполнена сначала по типу, а затем внутри каждого типа. Все числа будут идти перед строками.


Практические рекомендации

  • Для индексов и последовательностей лучше использовать числовые ключи, так как они гарантируют естественный порядок и корректную работу диапазонных запросов.
  • Для уникальных идентификаторов, где важна строгость типов, никогда не смешивать строки и числа.
  • При использовании методов keys() или entries() учитывать сортировку по числовому значению, особенно если планируется постобработка данных.
  • Для дробных ключей и таймстампов проверять точность чисел при сравнении, чтобы избежать ошибок при поиске.

Интеграция числовых ключей с асинхронными операциями

Idb-keyval работает с промисами, что позволяет строить последовательные операции с числовыми ключами:

import { set, get, keys } from 'idb-keyval';

async function addSequentialItems() {
  for (let i = 1; i <= 5; i++) {
    await set(i, `Элемент ${i}`);
  }

  const storedKeys = await keys();
  console.log(storedKeys); // [1, 2, 3, 4, 5]
}

addSequentialItems();

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


Заключение по особенностям

Числовые ключи в Idb-keyval представляют собой мощный инструмент для создания упорядоченных коллекций данных. Их преимущества проявляются при сортировке, диапазонных запросах и построении индексов. Правильное использование числовых ключей требует внимательности к типам и точности значений, но обеспечивает высокий уровень контроля и предсказуемое поведение при работе с IndexedDB.