Основные характеристики IndexedDB и базовая терминология
В этой статье описаны ключевые характеристики IndexedDB и представлена важная терминология, относящаяся к пониманию API IndexedDB.
Вам также могут быть полезны следующие статьи:
- Подробный учебник по использованию API см. в статье Использование IndexedDB.
- Для получения справочной документации по API IndexedDB обратитесь к основной статье API IndexedDB и ее подразделам, в которых документируются типы объектов, используемых IndexedDB.
- Дополнительную информацию о том, как браузер обрабатывает хранение данных в фоновом режиме, см. в статье Квоты хранилища браузера и критерии удаления.
Основные характеристики
IndexedDB — это способ постоянно хранить данные внутри браузера пользователя. Поскольку он позволяет создавать веб-приложения с богатыми возможностями запросов независимо от доступности сети, эти приложения могут работать как онлайн, так и офлайн. IndexedDB полезен для приложений, хранящих большое количество данных (например, каталог DVD в библиотеке), и приложений, которым не требуется постоянное подключение к Интернету для работы (например, почтовые клиенты, списки дел и блокноты).
IndexedDB позволяет хранить и извлекать объекты, которые индексируются с помощью «ключа». Все изменения, вносимые в базу данных, происходят в рамках транзакций. Как и большинство веб-хранилищ, IndexedDB следует политике одного источника. Таким образом, хотя вы можете получить доступ к сохраненным данным в пределах одного домена, вы не можете получить доступ к данным на разных доменных именах.
Если у вас есть представления, полученные при работе с другими типами баз данных, при работе с IndexedDB вы можете столкнуться с некоторыми особенностями. Поэтому важно помнить о следующих ключевых характеристиках IndexedDB:
-
Базы данных IndexedDB хранят пары ключ-значение. Значения могут быть сложными структурированными объектами, а ключи могут быть свойствами этих объектов. Вы можете создавать индексы, использующие любые свойства объектов для быстрого поиска, а также для упорядоченной перечисления. Ключи могут быть двоичными объектами.
-
IndexedDB построен на транзакционной модели базы данных. Все, что вы делаете в IndexedDB, всегда происходит в контексте транзакции. API IndexedDB предоставляет множество объектов, представляющих индексы, таблицы, курсоры и т. д., но каждый из них связан с определенной транзакцией. Таким образом, вы не можете выполнять команды или открывать курсоры вне транзакции. У транзакций есть четко определенный жизненный цикл, поэтому попытка использования транзакции после ее завершения вызывает исключения. Кроме того, транзакции автоматически подтверждаются, если новые запросы не выполняются, когда транзакция активна.
Эта модель транзакций очень полезна, если учесть, что может произойти, если пользователь откроет два экземпляра вашего веб-приложения в двух разных вкладках одновременно. Без транзакционных операций два экземпляра могли бы мешать друг другу при модификациях. Если вы не знакомы с транзакциями в базе данных, прочитайте статью Википедии о транзакциях. Также см. транзакцию в разделе «Определения».
-
API IndexedDB в основном асинхронный. API не возвращает данные, а вместо этого принимает функцию обратного вызова. Вы не «храните» значение в базе данных или не «извлекаете» значение из базы данных синхронным способом. Вместо этого вы «запрашиваете» выполнение операции базы данных. Вы уведомляетесь событием DOM, когда операция завершается, и тип события указывает, выполнена ли операция успешно или с ошибкой.
-
IndexedDB использует множество запросов. Запросы — это объекты, которые получают события DOM об успехе или неудаче, упомянутые ранее. У них есть
onsuccessиonerrorсвойства, и вы можете вызыватьaddEventListener()иremoveEventListener()на них. У них также естьreadyState,result, иerrorCodeсвойства, которые показывают состояние запроса. Свойствоresultособенно важно, так как оно может быть разным, в зависимости от того, как запрос был сгенерирован (например, экземплярIDBCursorили ключ для значения, которое вы только что вставили в базу данных). -
IndexedDB использует события DOM для уведомления о доступности результатов. События DOM всегда имеют свойство
type(в IndexedDB оно чаще всего устанавливается в"success"или"error"). События DOM также имеют свойствоtarget, которое указывает направление события. В большинстве случаевtargetсобытия — это объектIDBRequest, сгенерированный в результате выполнения операции базы данных. События успеха не «поднимаются вверх» и не могут быть отменены. События ошибок, с другой стороны, поднимаются вверх и могут быть отменены. Это очень важно, так как события ошибок прерывают любые выполняемые транзакции, если они не отменены. -
IndexedDB является объектно-ориентированным. IndexedDB не является реляционной базой данных с таблицами, представляющими коллекции строк и столбцов. Это важное и фундаментальное различие влияет на то, как вы проектируете и разрабатываете свои приложения.
В традиционном реляционном хранилище данных у вас есть таблица, хранящая коллекцию строк данных и столбцов именованных типов данных. IndexedDB, с другой стороны, требует создания хранилища объектов для типа данных и сохранения объектов JavaScript в этом хранилище. Каждое хранилище объектов может иметь набор индексов, что делает его эффективным при запросах и итерации.
Если вы не знакомы с объектно-ориентированными системами управления базами данных, прочитайте статью Википедии об объектных базах данных.
-
IndexedDB не использует язык запросов Structured Query Language (SQL). Он использует запросы к индексу, которые генерируют курсор, который вы используете для итерации по результатам.
Если вы не знакомы с NoSQL системами, прочитайте статью Википедии о NoSQL.
-
IndexedDB соответствует политике одного источника. Источник — это домен, протокол прикладного уровня и порт URL документа, в котором выполняется сценарий. Каждый источник имеет свой набор баз данных. Каждая база данных имеет имя, которое идентифицирует ее в рамках одного источника.
Безопасность, наложенная на IndexedDB, предотвращает доступ приложений к данным с другим источником. Например, в то время как приложение или страница в
http://www.example.com/app/может извлекать данные изhttp://www.example.com/dir/, так как у них один источник, оно не может извлекать данные изhttp://www.example.com:8080/dir/(разный порт) илиhttps://www.example.com/dir/(разный протокол), так как у них разные источники.Примечание: Содержимое окна третьей стороны (например,
<iframe>контент) может получить доступ к хранилищу IndexedDB для источника, в который он вложен, если браузер не настроен на отказ от сторонних файлов cookie (см. ошибку Firefox 1147821.)
Ограничения
IndexedDB предназначен для решения большинства задач, требующих хранения данных на стороне клиента. Однако он не предназначен для некоторых случаев, таких как:
- Международная сортировка. Не все языки сортируют строки одинаково, поэтому международная сортировка не поддерживается. Хотя база данных не может хранить данные в определённом международном порядке, вы можете отсортировать данные, которые вы прочитали из базы данных самостоятельно.
- Синхронизация. API не предназначен для обработки синхронизации с базой данных на стороне сервера. Вам нужно написать код, который синхронизирует базу данных IndexedDB на стороне клиента с базой данных на стороне сервера.
- Полнотекстовый поиск. API не имеет эквивалента оператору
LIKEв SQL.
Кроме того, имейте в виду, что браузеры могут удалять базу данных в следующих условиях:
- Пользователь запросил удаление. Многие браузеры имеют настройки, которые позволяют пользователям удалять все данные, хранящиеся для данного веб-сайта, включая куки, закладки, сохраненные пароли и данные IndexedDB.
- Браузер работает в режиме частного просмотра. Некоторые браузеры имеют режимы «частного просмотра» (Firefox) или «инкогнито» (Chrome). В конце сессии браузер удаляет базу данных.
- Достигнут предел дискового пространства или квоты.
- Данные повреждены.
- Произведена несовместимая модификация функции.
Точные обстоятельства и возможности браузера со временем меняются, но общая философия разработчиков браузеров заключается в том, чтобы по возможности сохранить данные.
Основная терминология
В этом разделе определены и объяснены основные термины, связанные с пониманием API IndexedDB.
База данных
база данных
Хранилище информации, обычно состоящее из одного или нескольких хранилищ объектов. Каждая база данных должна иметь следующее:
- Имя. Оно идентифицирует базу данных в рамках определённого источника и остаётся неизменным на протяжении всего её жизненного цикла. Имя может быть любой строкой (включая пустую строку).
- Текущая версия. При первом создании базы данных её версия равна целому числу 1, если не указано иное. Каждая база данных может иметь только одну версию в любой момент времени.
соединение с базой данных
Операция, создаваемая при открытии базы данных. Одна база данных может иметь несколько подключений одновременно.
долговечное хранение
В Firefox, IndexedDB раньше был долговечным, что означало, что в транзакции с записью событие complete срабатывало только тогда, когда все данные гарантированно были записаны на диск.
Начиная с Firefox 40, транзакции IndexedDB имеют ослабленные гарантии долговечности для повышения производительности (см. отчёт об ошибке Firefox 1112702), что соответствует поведению других браузеров, поддерживающих IndexedDB. В этом случае событие complete срабатывает после того, как операционная система получила команду записать данные, но потенциально до того, как эти данные фактически будут записаны на диск. Таким образом, событие может быть доставлено быстрее, чем раньше, однако существует небольшой шанс, что вся транзакция будет потеряна, если операционная система аварийно завершит работу или произойдёт отключение питания до записи данных на диск. Поскольку такие катастрофические события редки, большинство потребителей не должны беспокоиться об этом дополнительно.
Примечание: В Firefox, если по каким-либо причинам (например, вы храните критические данные, которые нельзя пересчитать позже) вам нужно гарантировать долговечность, вы можете принудительно выполнить запись транзакции на диск перед доставкой события complete создав транзакцию с экспериментальным (нестандартным) режимом readwriteflush (см. IDBDatabase.transaction.) В настоящее время это экспериментальная функция и может быть использована только если префикс dom.indexedDB.experimental установлен в true в about:config.
индекс
Индекс — это специализированное хранилище объектов для поиска записей в другом хранилище объектов, называемом ссылочным хранилищем объектов. Индекс — это постоянное хранилище ключ-значение, где часть значения записей — это ключевая часть записи в ссылочном хранилище объектов. Записи в индексе автоматически заполняются всякий раз, когда в ссылочном хранилище объектов вставляются, обновляются или удаляются записи. Каждая запись в индексе может указывать только на одну запись в ссылочном хранилище объектов, но несколько индексов могут ссылаться на одно и то же хранилище объектов. При изменении хранилища объектов все индексы, которые ссылаются на это хранилище, автоматически обновляются.
Кроме того, вы также можете искать записи в хранилище объектов, используя ключ.
Дополнительную информацию об использовании индексов см. в Использование IndexedDB. Справочную документацию по индексу см. в IDBKeyRange.
хранилище объектов
Механизм, с помощью которого данные хранятся в базе данных. Хранилище объектов постоянно хранит записи, которые представляют собой пары ключ-значение. Записи в хранилище объектов сортируются по ключам в порядке возрастания.
У каждого хранилища объектов должно быть уникальное имя в рамках своей базы данных. Хранилище объектов может иметь (по желанию) генератор ключей и путь к ключу. Если хранилище объектов имеет путь к ключу, оно использует встроенные ключи; в противном случае оно использует ключ вне строки.
Справочную документацию по хранилищу объектов см. в IDBObjectStore.
запрос
Операция, посредством которой осуществляется чтение и запись в базу данных. Каждый запрос представляет собой одну операцию чтения или записи.
транзакция
Атомарный набор операций доступа к данным и изменения данных в конкретной базе данных. С помощью него вы взаимодействуете с данными в базе данных. Фактически, любое чтение или изменение данных в базе данных должно происходить в рамках транзакции.
Соединение с базой данных может иметь несколько активных транзакций одновременно, при условии, что транзакции записи не имеют перекрывающихся областей. Область транзакций, которая определяется при её создании, определяет, с какими хранилищами объектов и индексами может взаимодействовать транзакция, и остаётся постоянной на протяжении всего срока жизни транзакции. Например, если соединение с базой данных уже имеет транзакцию записи с областью, которая охватывает только хранилище объектов flyingMonkey, вы можете начать вторую транзакцию с областью хранилищ объектов unicornCentaur и unicornPegasus. Что касается транзакций чтения, то их может быть несколько — даже перекрывающихся.
Ожидается, что транзакции будут кратковременными, поэтому браузер может прервать транзакцию, которая занимает слишком много времени, чтобы освободить ресурсы хранения, которые заблокировала долго выполняющаяся транзакция. Вы можете прервать транзакцию, что откатит изменения, внесённые в базу данных в рамках транзакции. И вам даже не нужно ждать начала или активности транзакции, чтобы прервать её.
Три режима транзакций: readwrite, readonly и versionchange. Единственный способ создать и удалить хранилища объектов и индексы — использовать транзакцию versionchange. Дополнительную информацию о типах транзакций см. в справочной статье для IndexedDB.
Поскольку всё происходит в рамках транзакции, это очень важная концепция в IndexedDB. Дополнительную информацию о транзакциях, особенно о том, как они соотносятся с версиями, см. в IDBTransaction, где также есть справочная документация.
версия
При первом создании базы данных её версия равна целому числу 1. У каждой базы данных в любой момент времени есть только одна версия; база данных не может существовать в нескольких версиях одновременно. Единственный способ изменить версию — открыть её с более высокой версией, чем текущая.
Ключ и значение
встроенный ключ
Ключ, хранящийся в составе хранимого значения. Он находится с помощью пути к ключу. Встроенный ключ можно сгенерировать с помощью генератора. После генерации ключа его можно сохранить в значении с помощью пути к ключу, или его можно использовать как ключ.
ключ
Значение данных, по которому хранимые значения организуются и извлекаются в хранилище объектов. Хранилище объектов может получить ключ из одного из трёх источников: генератора ключей, пути к ключу или явно заданного значения. Ключ должен быть типа данных, который имеет число, большее, чем предыдущее. Каждая запись в хранилище объектов должна иметь уникальный ключ внутри этого хранилища, поэтому вы не можете иметь несколько записей с одним и тем же ключом в данном хранилище.
Ключ может быть одного из следующих типов: строка, дата, число с плавающей точкой, двоичный блок, и массив. Для массивов ключ может варьироваться от пустого значения до бесконечности. И вы можете включать массивы в массивы.
Кроме того, вы также можете искать записи в хранилище объектов, используя индекс.
генератор ключей
Механизм для создания новых ключей в упорядоченной последовательности. Если у хранилища объектов нет генератора ключей, то приложение должно предоставить ключи для хранимых записей. Генераторы не разделяются между хранилищами. Это скорее деталь реализации браузера, так как в веб-разработке вы обычно не создаёте или не используете генераторы ключей.
путь к ключу
Определяет, откуда браузер должен извлечь ключ из хранилища объектов или индекса. Действительный путь к ключу может включать одну из следующих вещей: пустую строку, идентификатор JavaScript или несколько идентификаторов JavaScript, разделённых точками или массив, содержащий любой из них. Он не может содержать пробелы.
ключ вне строки
Ключ, хранящийся отдельно от хранимого значения.
значение
Каждая запись имеет значение, которое может включать всё, что может быть выражено в JavaScript, в том числе булево значение, число, строка, дата, объект, массив, выражение регулярного соответствия, undefined и null.
При хранении объекта или массива свойства и значения в этом объекте или массиве также могут быть любыми допустимыми значениями.
Файлы и блоки могут храниться, см. спецификацию.
Диапазон и область
курсор
Механизм для итерации по множеству записей с диапазоном ключей. У курсора есть источник, который указывает, по какому индексу или хранилищу объектов он итерирует. У него есть позиция в диапазоне, и он перемещается в направлении, которое увеличивается или уменьшается в порядке ключей записей. Справочную документацию по курсорам см. в IDBCursor.
диапазон ключей
Непрерывный интервал над типом данных, используемым для ключей. Записи могут извлекаться из хранилищ объектов и индексов с помощью ключей или диапазона ключей. Вы можете ограничить или отфильтровать диапазон с помощью нижних и верхних границ. Например, вы можете проитерировать по всем значениям ключа между x и y.
Справочную документацию по диапазону ключей см. в IDBKeyRange.
область
Набор хранилищ объектов и индексов, к которым применяется транзакция. Области чтений-только транзакций могут перекрываться и выполняться одновременно. С другой стороны, области транзакций записи не могут перекрываться. Вы по-прежнему можете начать несколько транзакций с одной и той же областью одновременно, но они просто встают в очередь и выполняются одна за другой.
Далее
Понимая ключевые характеристики и основные термины IndexedDB, мы можем перейти к более конкретным вопросам. Для получения руководства по использованию API см. Использование IndexedDB.
См. также
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Terminology