Статьи

IndexedDB: ключи: эффективное извлечение данных из базы данных

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

  • Array (Действителен, только если каждый элемент в массиве является допустимым ключом, а массив не содержит его самостоятельно. Также все нечисловые свойства игнорируются и не влияют на то, является ли массив допустимым ключом)
  • DOMString
  • Date (Primitivevalue (внутреннее свойство) объекта даты не может быть NaN)
  • Float (ключ не может быть NaN)

При сравнении ключей применяется порядок в списке выше. Массив больше чем все DOMString, DOMString больше чем…

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

Сложные ключи

IndexedDB API также поддерживает сложные ключи. Это ключи, которые ссылаются на свойства, вложенные в объект. Таким образом, вы сможете отфильтровать доступные данные, которые являются свойствами вложенного объекта. В приведенном ниже примере у нас есть объект person. Помимо имени и имени свойства он содержит свойство адреса. Это свойство address также является объектом, содержащим такие свойства, как city, street, … Если мы хотим отфильтровать данные по его городу, мы можем сделать это, определив ключ, такой как address.city.

 var person = {
  name: "name",
  firstname: "firstname",
   address: {
        street: "street",
        city: "city"    
    }

}

Начиная с Linq2IndexedDB 1.0.11 это также поддерживается для всех фильтров, даже для фильтров, которые не используют API IndexedDB. По этой причине рекомендуется использовать метод linq2IndexedDB.prototype.utilities.getPropertyValue для определения значения по имени его свойства. Необходимо предоставить два аргумента:

  • Первый аргумент — это объект, содержащий данные
  • Вторым аргументом является строка propertyName. Например, «address.city»

Возвращаемое значение метода — это значение в этом месте, если оно существует, в противном случае будет возвращено неопределенное значение.

Обратите внимание, что это вложение работает только для объектов. Если свойство содержит массив объектов, вы не сможете использовать этот способ для фильтрации ваших данных.

Ключи хранилища объектов

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

  • Встроенный ключ: ключ присутствует внутри объекта (в хранилище объектов должен быть определен KeyPath)
  • Внешний ключ: ключ предоставляется отдельно (в большинстве случаев значение ключа / значения будет первичным типом, таким как строка или число с плавающей запятой)

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

Индексные ключи

Ключи для индекса всегда определяются KeyPath. Эти ключи могут быть сложными ключами, как определено в разделе «Сложные ключи» выше. Каждый объект в хранилище объектов, содержащий индекс, который имеет значение для ключевого пути, к записи, будет добавлен. Ключом будет значение свойства, определяемое путем ключа. Например, у нас есть keyPath «имя». В приведенном ниже примере ключом записи индекса будет «Кристоф» и значение объекта «человек».

 var person = {
    name: "Degrave",

     firstname: "Kristof"
}

В индексе также может быть 2 особых случая. Первый — это уникальный атрибут. Это гарантирует, что значение для этого keyPath может быть определено только один раз в значении хранилища объектов. Это ограничение будет проверено при добавлении данных в хранилище объектов. Если существует объект с таким же значением для этого свойства, выдается ConstraintError.

Вторым атрибутом является multiEntry. Это позволяет иметь несколько значений только для одного ключа. Вместо добавления новой записи для каждого объекта с одинаковым значением ключ добавляется только один раз, а все объекты с одинаковым значением добавляются в коллекцию.

Вывод

Теперь вы должны понять, как ключи работают внутри IndexedDB API. С помощью сложных ключей вы сможете фильтровать данные с вложенным объектом, таким образом вам не нужно предоставлять хранилище объектов для каждого объекта, который вы хотите сохранить. Кроме того, среда Linq2IndexedDB также поддерживает эти сложные ключи, и вы даже можете использовать их в своих пользовательских фильтрах.