Библиотека Idb-keyval предоставляет удобный интерфейс для работы с IndexedDB через простой ключ-значение API. Одним из мощных приёмов является использование идентификаторов сущностей в качестве ключей. Это позволяет хранить, получать и обновлять данные конкретных объектов без необходимости полного обхода базы данных.
В классическом подходе ключом может быть строка или число. При работе
с сущностями, например, пользователями, товарами или сообщениями,
логично использовать их уникальный идентификатор (например,
id из базы данных) как ключ:
import { set, get, del } from 'idb-keyval';
const user = { id: 101, name: 'Алексей', email: 'alex@example.com' };
// Сохранение сущности с ключом на основе id
set(user.id, user).then(() => {
console.log('Пользователь сохранен');
});
// Получение сущности по идентификатору
get(101).then(value => {
console.log(value); // { id: 101, name: 'Алексей', email: 'alex@example.com' }
});
Преимущества подхода:
Idb-keyval позволяет быстро обновлять объекты по ключу, что особенно удобно для динамически изменяющихся сущностей:
get(101).then(user => {
if (user) {
user.email = 'alex_new@example.com';
return set(user.id, user);
}
}).then(() => console.log('Email обновлен'));
// Удаление сущности
del(101).then(() => console.log('Пользователь удален'));
Использование идентификаторов гарантирует, что обновление или удаление будет происходить только для конкретной сущности, без риска случайного затрагивания других объектов.
Для работы с множеством сущностей удобно использовать массивы
идентификаторов и методы Promise.all:
const users = [
{ id: 201, name: 'Ирина' },
{ id: 202, name: 'Сергей' },
{ id: 203, name: 'Мария' }
];
// Сохранение нескольких сущностей одновременно
Promise.all(users.map(user => set(user.id, user)))
.then(() => console.log('Все пользователи сохранены'));
// Получение нескольких сущностей
Promise.all([201, 202, 203].map(id => get(id)))
.then(values => console.log(values));
Такой подход позволяет легко синхронизировать данные с сервером или локально кэшировать список объектов без необходимости хранить их в одном массиве.
IndexedDB и, соответственно, Idb-keyval поддерживают сложные ключи, включая массивы. Это удобно для составных идентификаторов, например, при мультиключах:
const order = { orderId: 501, userId: 101, items: ['item1', 'item2'] };
// Составной ключ: [userId, orderId]
set([order.userId, order.orderId], order).then(() => console.log('Заказ сохранен'));
// Получение заказа по составному ключу
get([101, 501]).then(value => console.log(value));
Преимущества:
user:101, order:501.
Это помогает избегать конфликтов между разными сущностями.[postId, commentId] дает прямой доступ без поиска.Для приложения с пользователями и заказами структура локального хранения может выглядеть так:
// Пользователи
set('user:101', { id: 101, name: 'Алексей' });
set('user:102', { id: 102, name: 'Ирина' });
// Заказы
set(['order', 101, 501], { orderId: 501, userId: 101, items: ['item1'] });
set(['order', 101, 502], { orderId: 502, userId: 101, items: ['item2'] });
// Получение всех заказов пользователя 101
getAllOrdersForUser = async (userId) => {
const orders = [];
for (const orderId of [501, 502]) {
const order = await get(['order', userId, orderId]);
if (order) orders.push(order);
}
return orders;
};
Такой подход обеспечивает быстрый доступ к сущностям и поддерживает масштабируемость данных в IndexedDB через Idb-keyval.