Жизненный цикл базы данных в Dexie.js строится поверх механизма IndexedDB и управляется через декларативное версионирование схемы. Каждое изменение структуры хранения данных — добавление таблиц, индексов, изменение ключей или миграция данных — оформляется как новая версия базы данных, что позволяет контролировать эволюцию схемы без потери совместимости.
В основе модели лежит принцип: каждая версия базы — это неизменяемое описание структуры на определённый момент времени, а переход между версиями выполняется через управляемые миграции.
Dexie.js использует метод version() для определения
состояния схемы:
const db = new Dexie("AppDatabase");
db.version(1).stores({
users: "++id,name,email"
});
db.version(2).stores({
users: "++id,name,email,createdAt"
});
Каждый вызов version(n) фиксирует состояние схемы на
конкретном этапе.
Ключевой момент: Dexie не модифицирует предыдущие версии, они остаются частью истории миграций.
При вызове:
await db.open();
Dexie выполняет последовательность шагов:
Во время открытия создаётся транзакция уровня
versionchange, в рамках которой выполняются все
миграции.
Каждая новая версия активирует цепочку upgrade-операций:
Dexie позволяет явно описывать миграционную логику через
upgrade():
db.version(2).stores({
users: "++id,name,email,createdAt"
}).upgrade(tx => {
return tx.table("users").toCollection().modify(user => {
user.createdAt = Date.now();
});
});
Внутри upgrade-функции:
tx;Миграции выполняются в рамках одной транзакции IndexedDB. Это означает:
Dexie дополнительно управляет порядком выполнения версий, гарантируя последовательную миграцию:
v1 → v2 → v3 → v4
Пропуск промежуточных версий невозможен, даже если пользователь сразу подключился к последней.
Метод stores() определяет структуру object store:
db.version(3).stores({
users: "++id,name,email,age",
orders: "++id,userId,total"
});
Синтаксис описания индексов:
++id — автоинкрементный primary key;&email — уникальный индекс;*tags — multi-entry индекс;name — обычный индекс.Изменение строки stores() воспринимается как изменение
схемы, что автоматически инициирует upgrade при следующем открытии
базы.
Добавление таблицы:
db.version(4).stores({
users: "++id,name,email",
orders: "++id,userId,total",
logs: "++id,type,date"
});
Удаление таблицы происходит через исключение её из схемы новой версии:
db.version(5).stores({
users: "++id,name,email"
});
Dexie автоматически удаляет неописанные object stores при переходе на новую версию.
Dexie предоставляет гибкий механизм трансформации данных:
db.version(6).upgrade(async tx => {
const users = tx.table("users");
await users.toCollection().modify(user => {
user.fullName = `${user.firstName} ${user.lastName}`;
delete user.firstName;
delete user.lastName;
});
});
Особенности миграций:
Во время обновления:
Если приложение открыто в нескольких вкладках:
blocked.Конфликт возникает, когда:
Dexie предоставляет обработчик:
db.on("blocked", () => {
console.warn("Upgrade blocked by another tab");
});
Также существует событие:
versionchange — сигнал о необходимости закрыть
соединение.Dexie не поддерживает автоматический rollback схемы. Причины:
Поэтому:
Если версия базы не существует в браузере:
Если база уже существует:
Факторы, влияющие на скорость upgrade:
modify() операций;Оптимизация достигается через:
В приложениях с долгим сроком жизни базы данных типичная структура версий:
Dexie позволяет поддерживать линейную эволюцию схемы без необходимости ручного управления IndexedDB API.
Возможные сценарии:
Dexie реагирует следующим образом:
Версия базы в Dexie.js фактически выполняет функции:
Каждое изменение модели данных должно сопровождаться увеличением версии, иначе IndexedDB не инициирует upgrade-процесс.
Все стадии жизненного цикла базы тесно связаны с транзакционной моделью:
Это обеспечивает единообразие управления состоянием данных на всех этапах работы приложения.
Если база закрывается во время миграции:
Dexie гарантирует целостность состояния, исключая частично применённые миграции.