--- title: IndexedDB の主な特徴と基本用語 slug: Web/API/IndexedDB_API/Basic_Terminology tags: - Advanced - IndexedDB - terminology translation_of: Web/API/IndexedDB_API/Basic_Terminology ---
{{DefaultAPISidebar("IndexedDB")}}
この記事では IndexedDB の主な特徴を説明し、IndexedDB API の理解に関連する重要な用語を紹介しています。
また、以下の記事も参考になるでしょう。
IndexedDB は、ユーザーのブラウザー内にデータを永続的に保存するための方法です。ネットワークの利用可否にかかわらず、豊富なクエリー機能を備えたウェブアプリケーションを作成できるため、オンラインでもオフラインでも動作します。IndexedDB は、大量のデータを保存するアプリケーション (貸し出し用図書館の DVD カタログなど) や、インターネットへの持続的な接続を必要としないアプリケーション (メールクライアント、ToDo リスト、メモ帳など) に有効です。
IndexedDB では、「キー」に基づいてインデックス化されたオブジェクトを保存・取得することができます。データベースへの変更は、すべてトランザクション内で行われます。多くのウェブストレージ技術と同様に、IndexedDB は同一オリジンポリシーに従っています。そのため、ドメイン内の保存データにはアクセスできますが、異なるドメイン間のデータにはアクセスできません。
他の種類のデータベースでの作業を前提としていると、IndexedDB での作業に戸惑うことがあるかもしれません。そのため、以下のような IndexedDB の主な特徴を覚えておくことが重要です。
IndexedDB データベースは、キーと値の組を格納します。値は複雑な構造のオブジェクトで、キーはそのオブジェクトのプロパティです。オブジェクトの任意のプロパティを使用するインデックスを作成して、迅速な検索や並べ替えされた列挙を行うことができます。キーにはバイナリーオブジェクトを使用することができます。
IndexedDBは、トランザクションデータベースモデルに基づいて構築されています。IndexedDB で行うことは、常にトランザクションのコンテキストで行われます。IndexedDB の API には、インデックス、テーブル、カーソルなどを表す多くのオブジェクトが用意されていますが、これらはそれぞれ特定のトランザクションに関連付けられています。そのため、トランザクションの外でコマンドを実行したり、カーソルを開いたりすることはできません。トランザクションには十分に定義された有効期間があるため、トランザクションが完了した後に使用しようとすると、例外が発生します。また、トランザクションは自動コミットされ、手動でコミットすることはできません。
このトランザクションモデルは、ユーザーがウェブアプリケーションの 2 つのインスタンスを 2 つの異なるタブで同時に開いた場合のことを考えると、とても有用です。トランザクション操作がなければ、 2 つのインスタンスが互いの変更に干渉してしまう可能性があります。データベースのトランザクションに慣れていない方は、Wikipedia のトランザクションに関する記事をご覧ください。また、「定義」の章のトランザクションもご覧ください。
IndexedDB API は、ほとんどが非同期です。API は値を返すことでデータを提供するわけではありません。コールバック関数を渡す必要があります。同期的な方法でデータベースに値を「格納」したり、データベースから値を「取り出す」ことはしません。代わりに、データベース操作を「リクエスト」します。操作が終了すると DOM イベントで通知され、そのイベントの種類によって操作が成功したか失敗したかが分かります。最初は少し複雑に聞こえるかもしれませんが、そこには健全性を保つための対策が組み込まれています。これは、XMLHttpRequest が動作する方法と大きな違いはありません。
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 オブジェクトを永続化する必要があります。各オブジェクトストアには、クエリや反復処理を効率的に行うためのインデックスのコレクションを持つことができます。オブジェクト指向データベース管理システムに慣れていない方は、Wikipedia のオブジェクトデータベースの記事をお読みください。
IndexedDB は Structured Query Language (SQL) を使用しません。インデックスに対するクエリーを使用してカーソルを生成し、そのカーソルを使用して結果セットを反復処理します。NoSQL システムについてよく知らない方は、Wikipedia の 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/ (プロトコルが異なる) からは、オリジンが異なるためデータを取得することはできません。
IndexedDB は、クライアントサイドのストレージを必要とするほとんどのケースをカバーするように設計されています。しかし、以下のようないくつかのケースには対応していません。
LIKE
演算子に相当するものがありません。また、以下のような条件でブラウザーがデータベースを消去することがあるので注意が必要です。
正確な状況やブラウザーの機能は時間とともに変化しますが、ブラウザーベンダーの一般的な考え方は、可能な限りデータを残すために最善の努力をするというものです。
この節では、IndexedDB API の理解に関連する主な用語を定義および説明します。
現在のバージョン。データベースが最初に作成されたとき、特に指定がなければそのバージョンは整数の 1 です。各データベースは、常に 1 つのバージョンしか持つことができません。
Firefox では、IndexedDB は以前は永続性がありました。つまり、読み書きトランザクションにおいて、すべてのデータがディスクにフラッシュされたことが保証されたときにのみ、{{domxref("IDBTransaction.oncomplete")}} が発行されていました。
Firefox 40 では、IndexedDB トランザクションは、パフォーマンスを向上させるために、他の IndexedDB に対応するブラウザーと同様に永続性の保証を緩和しています ({{Bug("1112702")}} を参照)。この場合、 {{Event("complete")}} イベントは、OS がデータの書き込みを指示した後に発生しますが、そのデータが実際にディスクにフラッシュされる前に発生する可能性もあります。そのため、イベントは以前よりも早く配信されるかもしれませんが、データがディスクにフラッシュされる前に OS がクラッシュしたり、システムの電源が切れたりすると、トランザクション全体が失われてしまう可能性がわずかながらあります。このような致命的な事象は稀であるため、ほとんどの人はこれ以上気にする必要はありません。
メモ: Firefox では、何らかの理由で永続性を確保したい場合 (たとえば、後で再計算できない重要なデータを保存している場合)、実験的な (標準外の) readwriteflush
モードを使用してトランザクションを作成することで、complete
イベントを配信する前にトランザクションをディスクに強制的にフラッシュさせることができます({{domxref("IDBDatabase.transaction")}} を参照)。これは現在実験的なものであり、about:config
で dom.indexedDB.experimental
設定項目が true
に設定されている場合にのみ使用できます。
データベースにデータを保存する仕組みです。オブジェクトストアはレコードを持続的に保持しており、これはキーと値の組です。オブジェクトストア内のレコードは、キーによって昇順に整列して保存されています。
すべてのオブジェクトストアには、そのデータベース内で一意となる名前が必要です。オブジェクトストアは、オプションでキージェネレーターとキーパスを持つことができます。オブジェクトストアにキーパスがある場合はインラインキー、ない場合はアウトオブラインキーが使用されます。
オブジェクトストアのリファレンス文書は、 {{domxref("IDBObjectStore")}} を参照してください。
特定のデータベースで行う、原子性を持つデータアクセスやデータ変更の操作のセットです。これは、データベース内のデータと対話する手段です。実際は、データベース内のデータの読み取りや変更はトランザクション内で実施しなければなりません。
書き込みトランザクションのスコープが重ならない限り、ひとつのデータベース接続で同時に複数のアクティブなトランザクションが存在できます。トランザクションのスコープは生成時に定義され、トランザクションがどのオブジェクトストアと対話できるかや、トランザクションの持続期間にわたって保持し続けるかを示します。よって例えば、データベース接続で flyingMonkey
オブジェクトストアのみ対象とするスコープを持つ書き込みトランザクションがすでに存在するとき、unicornCentaur
オブジェクトストアや unicornPegasus
オブジェクトストアをスコープで持つ別のトランザクションを開始できます。読み取りトランザクションは、スコープが重なっていても複数実行できます。
トランザクションは持続期間が短いものを除き、長時間のトランザクションがストレージ資源をロックする状況から解放するために、ブラウザーが終了させることができます。トランザクションは中止させることができ、トランザクションによるデータベースの変更箇所はロールバックされます。また、開始するトランザクションや中止するトランザクションを待つ必要はありません。
トランザクションには readwrite
、readonly
、versionchange
の 3 つのモードがあります。オブジェクトストアやインデックスの生成および削除は、versionchange
トランザクションを使用する場合に限り実行できます。トランザクションのタイプについて詳しくは、IndexedDB のリファレンスをご覧ください。
すべての操作はトランザクション内で発生しますので、トランザクションは IndexedDB の重要な概念です。トランザクションについて、特にバージョン付けとの関係については、{{domxref("IDBTransaction")}} および関連文書をご覧ください。ここにリファレンス文書もあります。
インデックスは参照先オブジェクトストア (referenced object store) から呼び出されて、別のオブジェクトストアのレコードを検索するための特別なオブジェクトストアです。インデックスは持続的なキーと値のストレージであり、インデックスのレコードの値は、参照先オブジェクトストアのレコードのキーです。インデックス内のレコードは、参照先オブジェクトストアでレコードが挿入、更新、削除されるたびに、自動的に収集されます。インデックス内の各レコードは参照先オブジェクトストア内のレコードをひとつだけ示すことができますが、複数のインデックスが同一のオブジェクトストアを参照することもできます。オブジェクトストアが変更されると、そのオブジェクトストアを参照するすべてのインデックスが自動的に更新されます。
代わりに、キーを使用してオブジェクトストア内のレコードを検索することもできます。
インデックスの使用法について詳しくは、IndexedDB を使用するをご覧ください。インデックスのリファレンス文書として、IDBKeyRange をご覧ください。
オブジェクトストアに保存された値は、このデータ値によって編成および取り出しされます。オブジェクトストアはキージェネレーター、キーパス、明示的に指定した値の、3 種類の生成源のいずれかからキーを得られます。キーは、自身の前にあるものより大きな数値を持つデータ型であることが必要です。オブジェクトストア内の各レコードはオブジェクトストア内で一意のキーを持たなければならず、オブジェクトストア内で複数のレコードが同じキーを持つことはできません。
キーは 文字列、date、浮動小数点数値、配列のいずれかの型を使用できます。配列では、キーは空の値から無限大までの範囲を使用できます。また、配列の中に配列を含めることができます。文字列または整数値のキーしか使用できないという条件はありません。
代わりに、インデックスを使用してオブジェクトストア内のレコードを検索することもできます。
それぞれのレコードは値を持っており、論理値、数値、文字列、date、オブジェクト、配列、正規表現、undefined、null を含む、JavaScript で表現可能なものをどれでも含むことができます。
オブジェクトまたは配列を保存する場合は、それらのプロパティや値もまた、有効な値をどれでも持つことができます。
キーとして使用する、何らかのデータ型の連続的な区間です。キーまたはキーレンジを使用して、オブジェクトストアやインデックスからレコードを取り出すことができます。下限または上限を使用して、レンジを制限またはフィルターリングできます。例えばキーが x から y の間であるすべての値に対して、反復処理を行うことができます。
キーレンジのリファレンス文書として、{{domxref("IDBKeyRange")}} をご覧ください。
IndexedDB の主な特徴と主要な用語を理解できたら、より具体的な作業に入ることができます。API の使い方のチュートリアルについては、IndexedDB の使用をご覧ください。