Погрузитесь в IndexedDB

IndexedDB - одна из возможностей хранения, появившихся в браузерах на протяжении многих лет. Вот введение в IndexedDB, базу данных в Интернете, поддерживаемую всеми современными браузерами.

Введение в IndexedDB

IndexedDB - одна из возможностей хранения, появившихся в браузерах на протяжении многих лет. Это хранилище ключей / значений (база данных noSQL), которое считаетсяокончательное решение для хранения данных в браузерах.

Это асинхронный API, что означает, что выполнение дорогостоящих операций не будет блокировать поток пользовательского интерфейса, создавая небрежную работу для пользователей. Он может хранить неограниченное количество данных, хотя при превышении определенного порога пользователю предлагается установить более высокие ограничения для сайта.

Этоподдерживается во всех современных браузерах.

Он поддерживает транзакции, управление версиями и обеспечивает хорошую производительность.

Внутри браузера мы также можем использовать:

  • Печенье: может содержать очень небольшое количество строк
  • Веб-хранилище(или DOM Storage), термин, который обычно обозначает localStorage и sessionStorage, два хранилища ключей / значений. sessionStorage, не сохраняет данные, которые очищаются при завершении сеанса, в то время как localStorage сохраняет данные между сеансами

Недостаток локального / сеансового хранилища заключается в том, что он ограничен небольшим (и непоследовательным) размером, при этом реализация браузеров предлагает от 2 до 10 МБ пространства на сайт.

В прошлом у нас также былоВеб-SQL, оболочка вокруг SQLite, но теперь этоустарели не поддерживается в некоторых современных браузерах, он никогда не был признанным стандартом, поэтому его не следует использовать, хотя 83% пользователей имеют эту технологию на своих устройствах.согласно Могу ли я использовать.

Хотя технически вы можете создать несколько баз данных для каждого сайта, обычно высоздать единую базу данных, и внутри этой базы данных вы можете создатьнесколько хранилищ объектов.

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

Каждый магазин обычно содержит наборвещи, который может быть

  • струны
  • числа
  • объекты
  • массивы
  • даты

Например, у вас может быть магазин, в котором есть сообщения, а в другом - комментарии.

Хранилище содержит ряд элементов, имеющих уникальный ключ, который представляет способ, с помощью которого можно идентифицировать объект.

Вы можете изменять эти хранилища с помощью транзакций, выполняя операции добавления, редактирования и удаления, а также перебирая элементы, которые они содержат.

С появлениемОбещанияв ES6 и последующий переход API к использованию обещаний, API IndexedDB кажется немногостарая школа.

Хотя в этом нет ничего плохого, во всех примерах, которые я объясню, я буду использоватьОбещанная библиотека IndexedDBот Джейка Арчибальда, который представляет собой крошечный слой поверх IndexedDB API, чтобы упростить его использование.

Эта библиотека также используется во всех примерах на сайте Google Developers, касающихся IndexedDB.

Создать базу данных IndexedDB

Самый простой способ - использоватьunpkg, добавив это в заголовок страницы:

<script type="module">
import { openDB, deleteDB } from 'https://unpkg.com/idb?module'
</script>

Перед использованием IndexedDB API всегда проверяйте наличие поддержки в браузере, даже если он широко доступен, вы никогда не узнаете, какой браузер использует пользователь:

(() => {
  'use strict'

if (!(‘indexedDB’ in window)) { console.warn(‘IndexedDB not supported’) return }

//…IndexedDB code })()

Каксоздать базу данных

С помощьюopenDB():

(async () => {
  //...

  const dbName = 'mydbname'
  const storeName = 'store1'
  const version = 1 //versions start at 1

  const db = await openDB(dbName, version, {
    upgrade(db, oldVersion, newVersion, transaction) {
      const store = db.createObjectStore(storeName)
    }
  })
})()

Первые 2 параметра - это имя базы данных и версия. Третий параметр, который является необязательным, - это объект, содержащий функциювызывается только в том случае, если номер версии выше, чем текущая установленная версия базы данных. В теле функции вы можете обновить структуру (хранилища и индексы) базы данных.

Добавление данных в магазин

Добавление данных при создании магазина, его инициализация

Вы используетеputметод хранилища объектов, но сначала нам нужна ссылка на него, которую мы можем получить изdb.createObjectStore()когда мы его создаем.

Когда используешьput, значение - первый аргумент, ключ - второй. Это потому, что если вы укажетеkeyPathпри создании хранилища объектов вам не нужно вводить имя ключа при каждом запросе put (), вы можете просто записать значение.

Это населяетstore0как только мы его создадим:

(async () => {
  //...
  const dbName = 'mydbname'
  const storeName = 'store0'
  const version = 1

const db = await openDB(dbName, version,{ upgrade(db, oldVersion, newVersion, transaction) { const store = db.createObjectStore(storeName) store.put(‘Hello world!’, ‘Hello’) } }) })()

Добавление данных, когда магазин уже создан, с помощью транзакций

Чтобы добавлять элементы позже, вам нужно создатьсделка, который обеспечивает целостность базы данных (в случае сбоя операции все операции в транзакции откатываются, и состояние возвращается к известному состоянию).

Для этого используйте ссылку наdbPromiseобъект, который мы получили при вызовеopenDB, и запустите:

(async () => {
  //...
  const dbName = 'mydbname'
  const storeName = 'store0'
  const version = 1

const db = await openDB(/* … */)

const tx = db.transaction(storeName, ‘readwrite’) const store = await tx.objectStore(storeName)

const val = ‘hey!’ const key = ‘Hello again’ const value = await store.put(val, key) await tx.done })()

Получение данных из магазина

Получение одного предмета из магазина:get()

const key = 'Hello again'
const item = await db.transaction(storeName).objectStore(storeName).get(key)

Получение всех предметов из магазина:getAll()

Сохраните все ключи

const items = await db.transaction(storeName).objectStore(storeName).getAllKeys()

Получить все сохраненные значения

const items = await db.transaction(storeName).objectStore(storeName).getAll()

Удаление данных из IndexedDB

Удаление базы данных, хранилища объектов и данных

Удалить всю базу данных IndexedDB

const dbName = 'mydbname'
await deleteDB(dbName)

Чтобы удалить данные в хранилище объектов

Мы используем транзакцию:

(async () => {
  //...

  const dbName = 'mydbname'
  const storeName = 'store1'
  const version = 1

const db = await openDB(dbName, version, { upgrade(db, oldVersion, newVersion, transaction) { const store = db.createObjectStore(storeName) } })

const tx = await db.transaction(storeName, ‘readwrite’) const store = await tx.objectStore(storeName)

const key = ‘Hello again’ await store.delete(key) await tx.done })()

Переход с предыдущей версии базы данных

Третий (необязательный) параметрopenDB()функция - это объект, который может содержатьupgradeфункциявызывается только в том случае, если номер версии выше, чем текущая установленная версия базы данных. В теле этой функции вы можете обновить структуру (хранилища и индексы) базы данных:

const name = 'mydbname'
const version = 1
openDB(name, version, {
  upgrade(db, oldVersion, newVersion, transaction) {
    console.log(oldVersion)
  }
})

В этом обратном вызове вы можете проверить, с какой версии обновляется пользователь, и соответственно выполнить некоторые операции.

Вы можете выполнить миграцию из предыдущей версии базы данных, используя этот синтаксис

(async () => {
  //...
  const dbName = 'mydbname'
  const storeName = 'store0'
  const version = 1

const db = await openDB(dbName, version, { upgrade(db, oldVersion, newVersion, transaction) { switch (oldVersion) { case 0: // no db created before // a store introduced in version 1 db.createObjectStore(‘store1’) case 1: // a new store in version 2 db.createObjectStore(‘store2’, { keyPath: ‘name’ }) } db.createObjectStore(storeName) } }) })()

Уникальные ключи

createObjectStore()как вы можете видеть вcase 1принимает второй параметр, указывающий индексный ключ базы данных. Это очень полезно при хранении объектов:put()вызовы не нуждаются во втором параметре, но могут просто принимать значение (объект), и ключ будет сопоставлен со свойством объекта с таким именем.

Индекс дает вам возможность получить значение позже по этому конкретному ключу, и он должен быть уникальным (каждый элемент должен иметь свой ключ).

Для ключа можно установить автоматическое приращение, поэтому вам не нужно отслеживать его в клиентском коде:

db.createObjectStore('notes', { autoIncrement: true })

Используйте автоматическое увеличение, если ваши значения уже не содержат уникальный ключ (например, если вы собираете адреса электронной почты без связанного имени).

Проверить, существует ли магазин

Вы можете проверить, существует ли уже хранилище объектов, вызвавobjectStoreNames()метод:

const storeName = 'store1'

if (!db.objectStoreNames.contains(storeName)) { db.createObjectStore(storeName) }

Удаление из IndexedDB

Удаление базы данных, хранилища объектов и данных

Удалить базу данных

await deleteDB('mydb')

Удалить хранилище объектов

Хранилище объектов можно удалить только в обратном вызове при открытии базы данных, и этот обратный вызов вызывается только в том случае, если вы укажете версию выше, чем та, которая установлена в настоящее время:

const db = await openDB('dogsdb', 2, {
  upgrade(db, oldVersion, newVersion, transaction) {
    switch (oldVersion) {
      case 0: // no db created before
        // a store introduced in version 1
        db.createObjectStore('store1')
      case 1:
        // delete the old store in version 2, create a new one
        db.deleteObjectStore('store1')
        db.createObjectStore('store2')
    }
  }
})

Для удаления данных в хранилище объектов используйте транзакцию

const key = 232 //a random key

const db = await openDB(/*...*/)
const tx = await db.transaction('store', 'readwrite')
const store = await tx.objectStore('store')
await store.delete(key)
await tx.complete

Есть еще кое-что!

Это только основы. Я не говорил о курсорах и более сложных вещах. В IndexedDB есть еще кое-что, но я надеюсь, что это даст вам фору.

Скачать мою бесплатнуюРуководство для начинающих по JavaScript


Больше руководств по браузеру: