IndexedDB - What is Key, keyPath and indexName?

indexeddb promise
indexeddb react
indexeddb security
indexeddb library
indexeddb createobjectstore
indexeddb vs localstorage
idb is not defined
angular indexeddb

I am coming from MySQL and I am used to the conventional database table scheme. I am having trouble understanding IndexedDB and some of its terminology. I looked up these definitions in the documentation:

Key A data value by which stored values are organized and retrieved in the object store.

indexName The name of the index to create.

keyPath The key path for the index to use.

Basically, Key is like a Primary Key in MySQL, right? Is indexName the same thing as a column? And I don't understand what a keyPath is.

Can someone explain these for me? Thank you again for you patience :).

Yes, key is like a primary key in SQL. But others seem to be missing an example explaining the main part of your question, and that is the distinction between indexName and keyPath. Per the Mozilla page on creating an index,

indexName The name of the index to create. Note that it is possible to create an index with an empty name.

keyPath The key path for the index to use. Note that it is possible to create an index with an empty keyPath, and also to pass in a sequence (array) as a keyPath.

The indexName is what you use to access that index. Indexes are used to search that "column" in the database. The keyPath is the actual name of the "column." See other questions and answers for what forms a keyPath may take. Note that "column" is not technically correct, but I'm using it because that's what you used.

For example, suppose your data has the column hours and you want to be able to search your database on that column. When creating your database you would create an index for that column:

objectStore.createIndex(indexName, keyPath, { unique: false });

where indexName can be anything you want, let's say hoursColumn, and keyPath would be hours.

objectStore.createIndex("hoursColumn", "hours", { unique: false });

unique: false just means that other rows of data may have the same value for hours.

I can write data to the objectStore as follows:

db.transaction(storeName, "readwrite").objectStore(storeName).add({hours: 20, minutes: 30});

So to search your data on the column hours, you could write:

var data = db.transaction(storeName).objectStore(storeName).index("hoursColumn").get(20)

and the result would be the first row of data where hours = 20, e.g. {hours: 20, minutes: 30}

So to summarize, indexName is just what you call the index you created that you want to search, and keyPath is the actual name of the stored data on which you want to search.

IDBObjectStore.keyPath, Bear in mind that IndexedDB indexes can contain any JavaScript data type; IndexedDB uses the structured createIndex(indexName, keyPath); var myIDBIndex = objectStore. keyPath: The key path for the index to use. name is the store name, e.g. "books" for books, keyOptions is an optional object with one of two properties: keyPath – a path to an object property that IndexedDB will use as the key, e.g. id. autoIncrement – if true, then the key for a newly stored object is generated automatically, as an ever-incrementing number.

Indexes are a way to make it possible to query data in the indexeddb database. As you know objects are stored into the objectstores. These objectstore don't have a schema like you have in an normal SQL database.

An index exists out of 3 important properties:

indexName: The indexname is just a name you provide to the index. You will need this name if you want to use the index to query data.

keyPath: This defines which property of the object you want to address in your index. For example: you have an object

{ foo: "bar" } 

and you want to query on the foo property, "foo" will be your keypath. The keypath can even go further. You can access nested properties

{ foo: { bar: "bla" } }

If you want to query the bar property the keypath will be "foo.bar"

key: The keys are the values inside the keypath. As you mentioned this key is unique for the index, but this doens't mean this value must be unique over all your objects in the objectstore.

The indexes in the indexeddb work like this: When you create an index, it creates a new objectstore in which the object will be stored. Instead of storing these object bosed on primary key they are stored based on the values present in the keypath. This means that for a single key in an index you can have multiple objects. So if you start querying an index, it will filter on the keys and return the values that are present in these keys.

Hope this makes indexes clear for you.

For some more info I have written some blogpost about it: info about using keys and Indexeddb basics

IDBObjectStore.createIndex(), A key path is a property that always exists and contains a unique value. For example, in the case of a "people" object store we could choose the  The key generator creates a unique value for every object added to the object store. By default, if we don't specify a key, IndexedDB creates a key and stores it separately from the data. upgradeDb.createObjectStore('notes', {autoIncrement:true});

I am updating my answer here having re-read the topic of Keys and Indexes. Coming from a MySQL background they are indeed confusing with IndexedDB.

(Please see https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB#gloss_outofline_key)

Indexes

Typically these occur on elements within your "row" - so for example if you had a row: {Hello:"World",Foo:"Bar} in your database you could set an index (of any name) on say Hello. This would be like your indexes in MySQL.

Keys

So where Indexes can have multiple, Keys must (as the earlier answer mentions) be unique like MySQL Primary keys. Why this gets confusing is that you can also filter/search your data by Keys as well as Indexes. (see https://developer.mozilla.org/en-US/docs/Web/API/IDBKeyRange) The difference appears that Key searches appear to be more Ranges (like A-F or > 5 AND < 10) rather than specific values.

There is a very interesting explanation here about keys:

https://golb.hplar.ch/2017/09/A-closer-look-at-IndexedDB.html#primary-keys

Basically it explains that there are 4 types of keys within IndexedDB:

  1. out-of-line : you provide the key yourself on each insert
  2. out-of-line auto generated : primary key (i.e. AutoIncrement) number generated automatically
  3. inline : the contents of field form the index (this is typical to say a MySQL database but must then be unique)
  4. inline auto generated: hidden field (visible in console) added and is accessible through code but not related directly to the object data.

The difference between 2 and 4 is that 2 doesn't get a defined Name, whereas 4 (like a Primary Key in MySQL) does. You could then update (but not insert) on the ID field you've named in 4.

On an aside I believe its called a Keypath because you can call field.subproperty which is quite nice. Please also make sure your keys are spelt correctly! Obvious mistake.

Indexed Database API 2.0, Key/value storage: value can be (almost) anything, multiple key types. keyPath – a path to an object property that IndexedDB will use as the key, e.g. id . name – index name,; keyPath – path to the object field that the index  A keypath is how you indicate to indexedDB which properties of your object play a special role. Similar to how you would indicate to an SQL database that a certain column in a table is the primary key of the table, or how you could tell a database to create an index on one or more particular columns in a table.

Key       = Row Item
indexName = Column name
keyPath   = Column name

Working with IndexedDB | Web, IndexedDB.IDBObjectStore. latest (4.0.0) Type alias for IndexName an array key. If the multiEntry flag is unset, then a single record whose key is an array key is added to the index. Returns the key path of the store, or empty array if none  When you create your object store, you provide a name and a map of options. One option is the keypath, which is basically the property of your data expected to hold a value. The second option is a key called autoIncrement. This defaults to false, but if you set it to true, you get nicely autoincrementing keys. Here's an example by itself:

IndexedDB, type ObjectStoreIndex struct { Name string `json:"name"` // Index name. KeyPath KeyPath `json:"keyPath"` // Index key path. Unique bool `json:"unique"` // If true,  I want to create and use two IndexedDB indices, one with a simple keyPath and the other with a complex keyPath. Although the creation is successful in every browser I tried, the indices do not seem to be filled correctly in most. The procedure I'm using (self-contained test case at the end of the question) is:

Database.IndexedDB.IDBObjectStore - purescript-indexeddb, { "name": "keyPath", "$ref": "KeyPath", "description": "Object store key path." }, { "​name": "autoIncrement", "type": "boolean", "description": "If true, object store has  The keyPath read-only property of the IDBObjectStore interface returns the key path of this object store. If this property is null, the application must provide a key for each modification operation. Note: This feature is available in Web Workers .

indexeddb, keyPath(); } RefPtr<DOMStringList> IDBObjectStore::indexNames() const context, JSValue key, ExceptionCodeWithMessage& ec) { LOG(IndexedDB,  The keys in for an index are always defined by a KeyPath. These keys can be complex keys as defined in the section “Complex keys” above. Every object in the object store keeping the index that has

Comments