Это хранилище ключей/значений (база данных noSQL), которое считается окончательным решением для хранения данных в браузерах. IndexedDB является асинхронным API. Это означает, что выполнение приоритетных операций не будет блокировать поток пользовательского интерфейса. IndexedDB может хранить неопределенный объем данных, который зависит от пользователя.
Он поддерживает транзакции, управление версиями и обеспечивает хорошую производительность.
Внутри браузера мы также можем использовать:
- Cookies, которые могут содержать небольшое количество строк.
- DOM-хранилище (или Web-хранилище) – термин, который обычно определяет localStorage и sessionStorage два хранилища типа ключ/значение. sessionStorage не сохраняет данные, которые очищаются после завершения сеанса, а localStorage сохраняет.
Локальное/сеансовое хранилище имеет недостаток, заключающийся в ограничении доступного пространства: от 2 Мб до 10 Мб места на сайт.
В прошлом был Web SQL – оболочка для SQLite. Но теперь Web SQL устарел и не поддерживается в некоторых современных браузерах. Он никогда не был общепризнанным стандартом, поэтому его не следует использовать, однако 83% пользователей все же имеют эту технологию на своих устройствах в соответствии с Can I Use.
Хоть и технически можно создать несколько баз данных для сайта, обычно создается одна. Внутри этой базы данных можно создать несколько хранилищ. База данных является частной для домена, поэтому один сайт не может получить доступ к хранилищам IndexedDB другого.
Каждое хранилище содержит множество элементов, например:
- строки
- числа
- объекты
- массивы
- даты
К примеру, может существовать два хранилища: одно будет содержать посты, другое – комментарии.
Хранилище содержит ряд элементов, имеющих уникальный ключ, который представляет способ идентификации объекта.
Эти хранилища можно изменять с помощью транзакций, выполняя операции добавления, изменения и удаления, а также проходя по содержащимся в них элементам.
С появлением Promises в ES2015 и последующим переходом API на использование promises, API IndexedDB кажется немного устаревшим.
Импортируем библиотеку idb , используя: yarn add idb
А затем подключим её к странице, используя Webpack, Browserify или любую другую систему сборки, или просто: <script src=”https://proglib.io/p/node_modules/idb/lib/idb.js”></ script> .
Перед использованием API IndexedDB всегда проверяйте наличие поддержки в браузере. Вы никогда не знаете, какой браузер использует пользователь:
Как создать базу данных
Первые два параметра очевидны. Третий параметр, который является необязательным, – это обратный вызов, вызываемый только в том случае, если номер версии выше текущей установленной версии базы данных. В теле функции обратного вызова можно обновить структуру (хранилища и индексы) БД.
Мы используем upgradeDB для обратного вызова, чтобы определить, что пришло время обновить базу данных, если это необходимо.
Создание хранилища объектов
Хранилище объектов создается или обновляется в обратном вызове с помощью: db.createObjectStore(‘storeName’, options) .
Если установлена предыдущая версия, обратный вызов позволяет выполнить миграцию:
createObjectStore() , как вы можете видеть в case 1 , принимает второй параметр, который указывает индексный ключ базы данных. Это очень полезно при хранении объектов: вызовы put() не требуют второго параметра, но могут просто принимать значение (объект), и ключ будет сопоставлен со свойством объекта с таким именем.
Индекс дает вам возможность получить значение по этому определенному ключу, и он должен быть уникальным (каждый элемент должен иметь уникальный ключ).
Ключ можно настроить на автоматическое увеличение, поэтому вам не нужно отслеживать его на клиентской стороне. Если вы не укажете ключ, IndexedDB создаст его “прозрачно” для нас:
Также можно указать конкретное поле значения объекта для автоматического приращения:
Как правило, используется автоматическое увеличение, если значения уже содержат уникальный ключ (например, адрес электронной почты пользователей).
Использование индексов – это способ извлечения данных из хранилища объектов. Индекс определяется вместе с созданием базы данных в idb.open() следующим образом:
unique определяет, должно ли значение индекса быть уникальным, и никакие повторяющиеся значения не могут быть добавлены.
Вы можете получить доступ к уже созданному хранилищу объектов с помощью метода upgradeDb.transaction.objectStore() .
Можно проверить, существует ли хранилище объектов, вызвав метод objectStoreNames() :
Удаление базы данных
Удаление хранилища объектов
Хранилище объектов может быть удалено в обратном вызове только при открытии БД, и этот обратный вызов выполняется только в том случае, если указывается версия, превышающая установленную в настоящий момент:
Чтобы удалить данные в хранилище объектов, используйте эту транзакцию:
Вы можете использовать метод put() хранилища объектов, но сначала необходимо получить ссылку на него, которую можно достать из upgradeDB.createObjectStore() .
При использовании put значение является первым аргументом, а ключ – вторым. Это сделано специально, потому что если вы задаете keyPath при создании хранилища объектов, вам не нужно вводить имя ключа в каждом запросе put. Можно просто написать значение.
Этот код заполняет store0 , как только мы создаем хранилище:
Чтобы позже добавить элементы, необходимо создать транзакцию. Это обеспечивает целостность базы данных (в случае сбоя операции выполняется откат всех операций в транзакции, и состояние возвращается в прежнее).
Для этого используйте ссылку на объект dbPromise , полученный при вызове idb.open() , и запустите:
API IndexedDB также предлагает метод add() , но поскольку put() позволяет как добавлять, так и обновлять элементы, проще просто использовать его.