IndexedDB

From Logic Wiki
Jump to: navigation, search


Introduction to IndexedDB: The In-Browser Database

http://www.codemag.com/Article/1411041

In general, there are two different types of databases: relational and document (also known as NoSQL or object). Relational databases like SQL Server, MySQL, and Oracle store sets of data in tables. Document databases like MongoDB, CouchDB, and Redis store sets of data as individual objects. IndexedDB is a document database that exists in a sandboxed context (enforced by respecting the same-origin policy) entirely within the browser.

Design Paradigms

The architecture of IndexedDB resembles similar types of design paradigms as found in some of the popular server-side NoSQL database implementations. Object-oriented data is persisted in what are called object stores and all actions are request-based and executed within a transaction scope. The event lifecycle gives you the ability to control the configuration of the database and errors are managed throughout the API via error bubbling.

Object Stores

The foundation of an IndexedDB database is the object store. If you are experienced in relational databases, you can generally equate an object store to a database table. Object stores include one or more indices that operate as a key/pair value in the store and provide a way to quickly locate data.

As you configure an object store, you must select a key type of the store. Keys can exist within a store as "in-line" or "out-of-line" keys. In-line keys enforce uniqueness in the object store by referencing a path in the data object. To illustrate, consider a Person object that includes an Email Address property. You could configure your store to use an in-line key of emailAddress that enforces uniqueness across the store via data in the persisted object. Alternatively, out-of-line keys identify uniqueness through values that are independent to the data. In this case, you can liken the out-of-line key to an integer value in a relational database that acts as the primary key for the record.

Transaction-Based

Unlike some traditional relational database implementations, every operation against the database is executed in the context of a transaction. Transaction scopes affect one or more object stores at a time and you define this by passing in an array of object store names in to the function that creates a transaction scope.

The secondary argument involved in creating a transaction is the transaction mode. When requesting a transaction, you must decide whether to request access in a read-only or read-write mode. Transactions are resource intensive, so if you have no need change data in a data store, you only need to request access to the collection of object stores in a read-only mode.

Listing 2 demonstrates how to create a transaction using the appropriate mode, and is discussed in detail in the Implementing Database-Specific Code section of this article.

Request-Based

There’s a recurring theme that you may have noticed up until this point. Each operation against the database is described as involving a request to open the database, access an object store, and so on. The IndexedDB API is inherently request-based, which is an indication of the asynchronous nature of the API. For each operation you execute against the database, you must first create a request for that operation. As the request is being fulfilled, you can respond to events and errors that are produced as a result of a request.

The code implemented in this article demonstrates how requests are used to open the database, create a transaction, read object store contents, write to an object store, and empty an object store.

Request Lifecycle of an Open Database

IndexedDB uses an even lifecycle to manage the open and configuration operations of the database. Figure 2 demonstrates how an open request raises the upgrade needed event under certain circumstances.

Another Option

Browser support for local databases didn’t begin with the IndexedDB implementation, but rather it’s a newer approach that has come after the WebSQL implementation. Similar to IndexedDB, WebSQL is a client-side database, but it’s implemented as a relational database that uses structured query language (SQL) to communicate with the database. The history surrounding WebSQL is full of twists and turns, but the bottom line is that none of the major browser vendors are continuing support for WebSQL.

If WebSQL is effectively an abandoned technology, why even bring it up? Interestingly, WebSQL enjoys solid support among browsers. Chrome, Safari, iOS Safari, and Android browsers all support WebSQL. Plus, not only do the latest versions of these browsers offer support, but support is available many versions behind the latest and greatest of these browsers. What's interesting is that if you add the support for WebSQL to support for IndexedDB, you find that all of a sudden, a great number of browser vendors and versions support some incarnation of an in-browser database.


So if your application is truly in need of a client-side database and you want to achieve the highest levels of adoption possible, perhaps your application may look to support a client-side data architecture that falls back to WebSQL if IndexedDB is not available. Although there’s a stark difference in how a document database and a relational database manage data, you can build an application that uses local databases as long as your have the right abstractions in place.

Is IndexedDB Right for My Application?

Now for the million dollar question: "Is IndexedDB right for my application?" As always, the answer is most certainly: "It depends." The first place you might look when attempting to persist data on the client is HTML5 local storage. Local storage enjoys widespread browser adoption and features a ridiculously easy-to-use API. The simplicity has its advantages, but liabilities are found in its inability to support complex search strategies, store large sets of data, and provide transactional support.

IndexedDB is a database. So when you’re trying to make a decision about the client, consider how you might select a database as a persistence medium on the server. Questions you may ask yourself to help determine if a client-side database is right for your application include:

  • Do your users access your application with browsers that support the IndexedDB API?
  • Do you need to store a significant amount of data on the client?
  • Do you need to quickly locate individual data points within a large set of data?
  • Does your architecture require transactional support on the client?

If you answer "yes" to any of these questions, there is a good chance that IndexedDB is a good candidate for your application.

Using IndexedDB

Now that you've had an opportunity to become familiar with some of the overall concepts, the next step is to begin implementing an application based on IndexedDB. One of the first steps required is to normalize the different browser implementations of IndexedDB. You can easily do this by adding some checks for the various vendor-specific options and set them equal to the official object names off the window object. The following listing demonstrates how the final result of window.indexedDB, window.IDBTransaction and window.IDBKeyRange are all updated to be set to the appropriate browser-specific implementations.

window.indexedDB = window.indexedDB ||
                  window.mozIndexedDB ||
                  window.webkitIndexedDB ||
                  window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction ||
                  window.webkitIDBTransaction ||
                  window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange ||
                  window.webkitIDBKeyRange ||
                  window.msIDBKeyRange;

Now that each of the database-related global objects hold the correct version, the application is ready to begin working with IndexedDB.


The rest can be read thru original article.