Удаление данных в Dexie.js строится поверх транзакций IndexedDB и
обеспечивает несколько уровней работы: удаление по первичному ключу,
массовое удаление через запросы и удаление целых коллекций результатов.
Основной метод для удаления одиночной записи —
table.delete().
Базовый сценарий удаления — работа с первичным ключом таблицы.
await db.users.delete(1);
В этом примере удаляется запись из таблицы users, у
которой первичный ключ равен 1.
Promise<void>Важно, что отсутствие записи не считается исключительной ситуацией. Удаление считается успешным даже если ключ отсутствует в хранилище.
Любая операция удаления в Dexie.js выполняется внутри транзакции.
Если delete() вызывается вне явной транзакции, Dexie
создаёт её автоматически:
await db.transaction('rw', db.users, async () => {
await db.users.delete(1);
});
Удаление внутри транзакции особенно важно при сложных бизнес-операциях, где требуется согласованность данных.
Dexie.js поддерживает удаление набора записей через запросы.
await db.users
.where('age')
.below(18)
.delete();
Promise<void>await db.orders
.where('createdAt')
.below(Date.now() - 30 * 24 * 60 * 60 * 1000)
.delete();
Удаление старых записей таким способом часто используется для очистки кэша или логов.
Любой результат запроса (Collection) может быть
полностью удалён:
const oldUsers = db.users.where('status').equals('inactive');
await oldUsers.delete();
Фактически collection.delete() и
where(...).delete() выполняют одинаковую роль, но
Collection позволяет:
.and(), .or() логические
цепочкиПример сложного удаления:
await db.users
.where('age').above(30)
.and(user => user.isBlocked === true)
.delete();
Dexie.js поддерживает удаление через диапазоны ключей IndexedDB:
await db.logs
.where('id')
.between(1000, 2000)
.delete();
Это эффективно, когда первичный ключ или индекс поддерживает упорядоченность.
Также можно использовать крайние границы:
await db.logs
.where('id')
.above(5000)
.delete();
При удалении записи Dexie автоматически:
Это означает, что разработчику не нужно вручную управлять индексными структурами.
Удаление в Dexie.js наследует ограничения IndexedDB:
Если требуется каскадное удаление, его необходимо реализовывать вручную:
await db.transaction('rw', db.users, db.posts, async () => {
await db.posts.where('userId').equals(1).delete();
await db.users.delete(1);
});
Типичные ситуации, которые могут привести к ошибкам:
TransactionInactiveError
Возникает при попытке выполнить удаление вне активной транзакции в специфических сценариях (например, после завершения async-цепочки).
Если запрос использует несуществующий индекс:
db.users.where('nonExistingField').delete();
Dexie выбросит ошибку на этапе построения запроса.
Удаление по первичному ключу:
Удаление через where():
Рекомендации по производительности:
.and() при больших наборах данныхDexie полностью поддерживает async/await, но также работает с цепочками:
db.users.delete(1)
.then(() => db.users.delete(2))
.then(() => console.log('done'));
Хотя такой стиль допустим, транзакционный подход предпочтительнее:
await db.transaction('rw', db.users, async () => {
await db.users.delete(1);
await db.users.delete(2);
});
Dexie поддерживает hooks, которые могут перехватывать операции удаления:
db.users.hook('deleting', (primKey, obj, transaction) => {
console.log('Удаляется:', primKey);
});
При массовом удалении важно учитывать ограничения памяти и времени выполнения:
await db.logs
.where('level')
.equals('debug')
.delete();
Если объём данных очень большой, возможен подход пакетного удаления:
while (true) {
const count = await db.logs
.where('level')
.equals('debug')
.limit(1000)
.delete();
if (!count) break;
}
IndexedDB сериализует транзакции, поэтому:
Удаление не зависит от версии схемы напрямую, но при миграциях:
await db.users.delete(999999);
Это поведение упрощает написание idempotent-логики, где удаление может выполняться без предварительной проверки существования записи.