Webアプリもオフライン実行? Indexed Databaseを使いこなそう:連載:人気順に説明する初めてのHTML5開発(1/2 ページ)
オフラインでもWebアプリ? それならブラウザ側でデータを管理できるKey-Value型簡易DB「Indexed Database」を使おう。
powered by Insider.NET
従来のWebアプリケーションでのデータ保存には、MySQL/Oracle/SQL Serverなど各データベース製品を利用してサーバサイドでデータをやりとりするのが一般的であった(ActiveXを利用すればJavaScriptコードからデータベース製品を利用することも可能)。
重要なデータを保存する場合には、今後もこの流れは変わることはない。ただ、個人で利用するだけのデータや、インターネットに接続できないオフライン環境でのアプリケーション利用時であればどうだろう。このようなケースでは、(クライアント環境で)ブラウザごとにデータを保存できる仕組みがあれば、非常に有効だ。
そこで登場するのが、今回紹介する「Indexed Database API」(以下、IndexedDB)だ。IndexedDBは、JavaScriptを使用してデータを管理できるキー/バリュー型の簡易データベースである。簡易とはいえ、インデックスの設置やトランザクションが利用できるなど、高度な機能も備えている。Web Storageと同様に、オリジン単位でデータを管理しているため、(もちろん)ほかのアプリケーションにデータが漏えいする心配はない。
IndexedDBのイメージは、図1のとおり。
リレーショナル・データベースの「テーブル」に相当するのが「オブジェクト・ストア」で、キー/バリュー型で格納されている「オブジェクト」が(リレーショナル・データベースの)「レコード」に相当する。また、インデックスを使用することでオブジェクト・ストア内のオブジェクトを効果的に検索できる。基本的にキーはオブジェクトを指定して取得する際に使用し、インデックスは特定範囲のオブジェクトをまとめて取得する際に使用する。キーおよびインデックスを利用したデータの検索、コーディング方法については後述する。
■Web Storageとの違い
キー/バリュー型のストレージと聞くと、第2回で触れたWeb Storageとの使い分けなどが気になる方も多いだろう。IndexedDBとWeb Storageは以下のような違いがある。
機能 | IndexedDB | Web Storage(localStorage) |
---|---|---|
オリジン単位でのデータの保存 | ○ | ○ |
トランザクション機能の提供 | ○ | × |
インデックス機能の提供 | ○ | × |
利用できるストア | 複数 | 単一 |
利用のお手軽さ | Web Storageよりは煩雑 | 容易 |
IndexedDBとWeb Storageの比較表 |
インデックスやトランザクションなどの機能を利用したい場合はIndexedDBを選択することになるだろう。ただし、提供される機能を活用するためにはWeb Storageに比べて手続きが煩雑になるので、シンプルなデータを手軽に保存したい場合はWeb Storageを使用する方がよい。
以下に、IndexedDBを利用できそうなシナリオを挙げてみよう。
(1)ブラウザ上でコメント付きブックマークを管理する
例えば、はてなブックマークなどのソーシャル・ブックマーク・サービスであればコメントを保有できるが、ブラウザの「お気に入り」機能はできない。しかしIndexedDBを利用すれば、ソーシャル・ブックマーク・サービスのように、コメント付きブックマークを管理するアプリケーションも開発しやすい。
(2)オフライン・アプリケーションで一時的なデータ保管場所に
HTML5でサポートされているオフライン・アプリケーション作成に欠かせない「Application Cache」と、IndexedDB/File APIを併用することで、Webアプリケーションでありながら、インターネットに接続できない環境でも、まるでデスクトップ・クライアント・アプリケーションのように動作するWebアプリケーションを作成できるようになる。
この2つのシナリオでは、Web Storageよりも、トランザクションやインデックス機能を保有するIndexedDBを使用する方が効率的である。
■IndexedDBの実装状況
気になるIndexedDBの実装状況だが、2012年1月の時点では、以下のとおりだ。
ブラウザ | 対応バージョン |
---|---|
Internet Explorer | 未実装 |
Firefox | 4.0以降*1 |
Chrome | 11.0以降*2 |
Safari | 未実装 |
Opera | 未実装 |
主要ブラウザにおけるIndexed Database APIの実装状況 *1 インターフェイスの一部に「moz」というプレフィックスが必要。 *2 インターフェイスの一部に「webkit」というプレフィックスが必要。 |
現時点では、主要ブラウザのうち、FirefoxとChromeのみの実装となる。IEでは、次期バージョンとなる「10」からIndexedDBに正式対応の予定だ。それ以外のブラウザも、これからIndexedDBに対応していくだろう。
なお、IndexedDBは2012年1月現在でも仕様が変わる「ワーキング・ドラフト」の段階のため、本稿の内容も今後の仕様変更により動作しなくなる可能性がある。また、動作が不安定な部分がある点だけはご理解いただきたい。本稿のサンプルは、2011年4月19日の段階のワーキング・ドラフトを基に作成している。
それでは、IndexedDBの利用方法を見てみよう。
■Indexed Database APIの対応を確認する方法
IndexedDBを利用するに当たっては、まずブラウザがIndexedDBを利用できるかを確認しなければならない。具体的なコードは、以下のとおりだ。
iif (window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB) {
// IndexedDBに関する処理を記述
} else {
window.alert("本ブラウザではIndexedDBが使えません");
}
windowオブジェクトのIndexedDBプロパティがある場合はIndexedDBが利用できるものとして実処理を、ない場合は「利用できない」ことを伝えるエラー・メッセージの表示などを行うのが一般的だ。なお現時点では、IndexedDBプロパティは、それぞれベンダ・プレフィックスを付けて、「webkitIndexedDB」「mozIndexedDB」のように記述しなければならない点にも注意してほしい。
では、使用方法を見てみよう。
■IndexedDBを使用して、個人用ブックマーク・アプリケーションを実装する
冒頭で触れたように、個人用の気になったサイトのブックマークを保存・管理する個人用ブックマーク・アプリケーションを例に、IndexedDBの利用方法を見てみよう。こちらから実際に試せる。なお、FirefoxとChromeでは、微妙に仕様が異なるため、サンプルはChromeのみでの動作を保証するものとする。
サンプルの実行結果は、図2〜4のとおりだ。
図2 IndexedDBに保存する値を、それぞれ入力している画面
[ページタイトル]と[ブックマークコメント]、[ブックマークURL]を記入したうえで[設定]ボタンをクリックすることで、IndexedDBに値を保存できる。
図3 キーを基に、値を取得している画面
IndexedDBに値を保存した後、区切り線の下に表示されている[取得したい値のキーを入力してください。]テキストボックスに、キーの値を入力し[値の取得]ボタンをクリックすると、入力したキーを基にデータを取り出すことができる。この例では「@IT」というキー名を入力しているが、当然ながら、[ページタイトル](=キー名)が「@IT」のブックマークを事前に保存していないと、このキーでは値がヒットしない。
今回のサンプルは、ボリュームもあるので、以下の3段階に分けて順に解説する。
- データベースの初期化
- データの追加とキーを利用したデータの取得
- インデックスの設定とカーソルによる検索
●IndexedDBに格納するオブジェクト
本サンプルでIndexedDBに格納するオブジェクトは、以下のとおりだ。以降のコードを読み解く際には、以下のオブジェクト構造を念頭に読み進めてほしい。
キー/オブジェクト名 | 概要 |
---|---|
BookmarkKey(in-line key) | ページ・タイトルを記載 |
Comment | ページに対するコメントを記載 |
URL | ページのURLを記載 |
IndexedDBで利用する主なオブジェクト |
IndexedDBでは、リレーショナル・データベースの主キーのように、レコード内に保存するキーとして利用するものを「in-line key」(インライン・キー)と呼ぶ。in-line keyは、後述するkeyPathプロパティに値が指定されている場合に利用されるキーだ。逆にkeyPathプロパティが指定されなかった場合はキーがオブジェクトの外部に存在することになるので、「out-of-line key」(アウトオブライン・キー)と呼ぶ。今回はin-line keyを利用する。
それぞれのキーの使い分けだが、オブジェクト内にキーにしたい値がある場合はinline-keyを、できればオブジェクトとキーを分けたい場合はout-of-line keyを使うとよいだろう。今の段階の仕様では、「どちらがよい」という指針があるわけではないので、プロジェクトとしてキーを管理しやすい方を選択すればよい。
では次のページから、具体的なコードについて見ていく。
記事タイトルの変更について
『スマートフォンとの相性は抜群! Indexed Databaseを使いこなそう』というタイトルにしていましたが、スマートフォンの標準ブラウザでは(記事公開時点で)「Indexed Database API」に対応していないため、現在のタイトルに変更しました。お詫びして訂正させていただきます。
Copyright© Digital Advantage Corp. All Rights Reserved.