web-dev-qa-db-ja.com

HTML5 IndexedDB、Web SQL Database、ブラウザ戦争

オフラインのデータベースストレージ要件を備えたWebアプリの開発を開始しています。要するに、アプリは以下で実行できるはずです。

  • 主要なデスクトップブラウザの1つ、Chrome優先
  • IOSのSafari
  • Androidのネイティブブラウザー(V8およびWebKitベース)

質問は、IndexedDBとWeb SQL Databaseのどちらを選択するかです。

Web SQLデータベースに関しては、一方で、上記のシナリオのいずれかで使用する準備ができています。一方、MozillaはFirefoxがFirefoxを実装することは決してないと述べており、HTML5 working draft に従って仕様は行き詰まりました:

この仕様は行き詰まりました。関心のあるすべての実装者は同じSQLバックエンド(Sqlite)を使用しましたが、標準化パスに沿って進むには複数の独立した実装が必要です。別の実装者がこの仕様の実装に興味を持つまで、SQLダイアレクトの記述は、単にSqliteへの参照として残されていましたが、これは標準では受け入れられません。独立したSQLバックエンドの実装に関心のある実装者である場合は、方言の仕様を記述できるように編集者に連絡してください。これにより、この仕様を前進させることができます。

IndexedDBはMozillaが提唱する代替手段ですが、Firefox 4でのみ提供されます。Microsoftは興味を示しており、Chromeも同様にサポートします。IndexedDBに関するAppleの計画は知りません。

個人的にWeb SQL Databaseを選択する傾向がありますが、SQLiteに慣れているという理由だけで、SQLのパワーと表現力が好きで、リレーショナルモデルを理解しています。私にとって、IndexedDBは不確実です。

とはいえ、間違った馬に賭けるのは怖いです。 IndexedDBが標準になったとしても、Web SQL Databaseのサポートが引き続き存在すると想定しても安全ですか?

(CouchDBに関するメモ:代替手段としても見ますか?)

44
ivo

リストした3つの要件をすべてサポートするのはWebSQLのみであると考えると、選択は簡単ではないでしょうか? SafariまたはAndroidの開発ロードマップに対する洞察がないため、入手可能なものを使用してください。

14
codelark

まあ、すべてのコンピューティングと同様に、ゲームは「抽象化」です。

SQLストアとキー/値ストアの両方で機能する適切なレイヤーを思い付くことができれば、理想的には問題から隔離され、特定のブラウザーで適切な実装をサポートできます。データモデルとアクセスパターンが最小公分母(つまり、k/vストア)に適合しない場合、それはそこで問題をほとんど解決します。

どちらかのストアを使用できる場合は、適切なアクセスレイヤーで作業し、その方向から問題にアプローチします。

バックエンドにk/vストアがあるからといって、データをk/vモデルのみとしてモデル化する必要があるわけではありません。基本的に、バックエンドにあるすべてのDBはk/vストアです。大量のデータがない場合は、多くのことができます。大量のデータを使用すると、ジャンプしなければならない可能性があるため、パフォーマンスが低下する可能性がありますが、少量のデータでは表示されない場合があります。すべてに依存します。

24
Will Hartung

IndexDB Polyfill があるため、私の推奨はIndexDBに移動です。

WebSQLをサポートするすべてのブラウザーは、この方法で IndexDB API をサポートできます。逆の方法は実装が非常に難しいので、DB APIを知っているすべてのブラウザーにアクセスしたい場合は、現在IndexDBが最良の選択です。


注:この質問は古くても関連性があるため、この質問に対する答えは更新に値すると思います。そして、リンクのみのソリューションでごめんなさい、だから私は通常長続きする宛先へのリンクだけを追加しました:W3CとGitHub

6
Tino

データベースには、キー/値ストアをはるかに超えるニーズがありますか?そうでない場合は、ローカルブラウザベースのデータベース抽象化のための多くのjavascriptパッケージを見つけました。そのようなパッケージの1つがjStoreです。

http://code.google.com/p/jquery-jstore/

最近、ローカルキー/値ストレージを追加するために使用しました。十分に文書化されており、統合時間はごくわずかでした-フラッシュローカルストレージを含むストレージバックエンドの配列をAPIを介してサポートします。

CouchDBは優れたソリューションです-あなたの問題と完全には一致しない問題のために。 couchone mobile をご覧ください。厳密に「Webアプリ」用ではありませんが、仕様にある程度の柔軟性がある場合は、実行可能なデータベース基盤を提供する可能性があります。

6
fish2000

IOS上のSafariの特定の要件では、WebSQL以外の選択肢はありません。 WebSQLは、OperaやBlackberryのような他のモバイルブラウザでサポートされています。IndexedDBを使用している場合でも、WebSQLサポートが削除されるとは思いません。

一方、ブラウザのストレージ戦争では、IndexedDBが勝ちます。 IEとFFはIndexedDBのみを持ちます。皮肉なことに、FFはSqliteの上にIndexedDBを実装しています。

私が言いたいのは、IndexedDBは単なるキーバリューストアではありません。インデックスとトランザクションがあります。これら2つだけで、結合、条件付き、並べ替えなど、SQLクエリのほぼすべての機能が実現します。非同期APIのため、最初は明らかではありません。

IndexedDBのパフォーマンスはWebSQLよりも優れています。より安全です。 JavaScriptのユースケースにより柔軟です。最後に、より使いやすくなりました。

ケースを説明するために、 my library のSudoコードを使用しますが、IndexedDB APIを直接使用できます。

「ピープル」ストアには、インデックスフィールド「name」とリストインデックスフィールド「hobby」があります。 JSONでは、

people = {
  name: 'Foo Bar',
  email: '[email protected]'
  hobby: ['camping', 'swimming']};

趣味が「キャンプ」である「人々」から名前を取得する。

var req = db.keys('people', 'hobby', IDBKeyRange.only('camping'));
req.done(function(campers) {
  db.keys('people', campers, 'name').done(function(names) {
     console.log(names);
  });
});

このコードの興味深い点は、シリアル化が含まれていないことです。したがって、非常に高速です。

次の例は、フレンドシップグラフクエリを示しています。 friendshipオブジェクトストアには、リストされたインデックスフィールドfriend_listが1つだけあります。アウトオブラインの主キーとしてピープルオブジェクトストアキーを使用します。 peopleオブジェクトストアには多くの属性があり、その中にはlocationフィールドがあります。クエリは、meother_guyを知っていて、「シンガポール」にいる友人のリストを見つけることです。

var q1 = new ydn.db.Iterator('friendship', 'friend_list', IDBKeyRange.only(me));
var q2 = new dn.db.Iterator('friendship', 'friend_list', IDBKeyRange.only(other_guy));
// if location is not indexed, a filtered value query is used.
var q3 = new ydn.db.Iterator('people', new ydn.db.Expression(['"location"', "'Singapore'", '=']));
// if location is indexed, an index query is used.
// var q3 = new ydn.db.Iterator('people', 'location', IDBKeyRange.only('Singapore'));
var current_loop = 2; // start from inner loop
var join_algo = function(keys, index_keys) {
  var advancement = [];
  advancement[keys.length - 1] = null;
  var has_adv = false;
  for (var i = 0; i < keys.length; i++) {
    if (!goog.isDef(keys[i])) {
      // completed iterator
      if (i != 0) {
        advancement[i] = false; // request to restart the iteration
        advancement[i - 1] = true; // advance outer iterator
        current_loop = i - 1;
      } // i == 0 means we are done.
     has_adv = true;
     break;
    }
  }
  if (!has_adv) {
    // continue looping current
    advancement[current_loop] = true;
  }
  return advancement;
}
var result = db.scan([q3, q1, q2], join_algo);
result.done(function(keys, index_keys, values) {
  console.log(values); // should get desire list of friends 
});

繰り返しますが、この結合クエリは単なるキースキャンであり、非常に高速です。デフォルトではscanはソート済みマージアルゴリズムを使用して一致するキーを見つけますが、ここでは単純なネストループ結合アルゴリズムを示します。したがって、テーブルの結合は可能ですが、結合アルゴリズムをコーディングする必要があります。しかし、ジグザグマージなどの新しいアルゴリズムは、すべての入力が並べ替えられ、カーソルが順調に進むことができ、さらに重要なことに、結合プロセスがデータベースにない外部の知識を活用できるため、Sqliteを使用した場合よりも高速です。 SQLでは、結合操作は不透明です。

それ以外のIndexedDBは、ストリーミングやmap/reduce処理などの手法を使用できます。

5
Kyaw Tun

2016年(この質問をしてから5年後)にこれに返信しますが、WebSQLの 非推奨に関するすべてはまだ有効です 。一方、IndexedDBは すべての主要なブラウザーベンダーのサポートを楽しんでいます

したがって、ここで同じ決定を下すことに直面する可能性がある人は、IndexedDBを使用してください。

ただし、ここで他の人によって暗示されているように、そのような決定は必ずしもなされなければならない決定ではありません。クライアントマシンで使用可能なデータベースを利用するライブラリを選択(または作成)するだけです。

BakedGoods は、いくつかの点ですでに提案されているライブラリとは異なります。最も適切なのは、利用するストレージタイプを明示的に指定できるようにし、開発者が意思決定プロセスに他の要因(パフォーマンス特性など)を導入できるようにすることです。

それにより、サポートされているデータベースタイプのいずれかでストレージ操作を実行することは問題です...

...両方のデータベースタイプに適切な操作オプションと同等の構成を指定します。

//If the operation is a set(), and the referenced structures 
//don't exist, they will be created automatically.

var webSQLOptionsObj = {
    databaseName: "Example_DB",
    databaseDisplayName: "Example DB",
    databaseVersion: "",
    estimatedDatabaseSize: 1024 * 1024,
    tableData: {
        name: "Main",
        keyColumnName: "lastName",
        columnDefinitions: "(lastName TEXT PRIMARY KEY, firstName TEXT)"
    }, 
    tableIndexDataArray: [name: "First_Name_Index", columnNames: "(firstName)"]
};

var indexedDBOptionsObj = {
    databaseName: "Example_DB",
    databaseVersion: 1,
    objectStoreData: {
        name: "Main",
        keyPath: lastName,
        autoIncrement: false
    },
    objectStoreIndexDataArray: [
        {name: "First_Name_Index", keyPath: "firstName", unique: false, multiEntry: false}
    ],
};

var optionsObj = {
    conductDisjointly: false, 
    webSQL: webSQLOptionsObj, 
    indexedDB: indexedDBOptionsObj
};

...および操作の実行:

bakedGoods.set({
    data: [
        {value: {lastName: "Obama", firstName: "Barack"}}, 
        {value: {lastName: "Biden", firstName: "Joe"}}
    ],
    storageTypes: ["indexedDB", "webSQL"],
    options: optionsObj,
    complete: function(byStorageTypeStoredItemRangeDataObj, byStorageTypeErrorObj){}
});

シンプルなインターフェースと比類のないストレージ施設サポートは、ストレージ施設固有の構成の一部がサポートされていないという代償を伴います。たとえば、複数列の主キーを持つWebSQLテーブルでのストレージ操作の実施はサポートしていません。

そのため、これらのタイプの機能を多用する場合は、他の場所を調べてください。

ああ、そして完全な透明性のために、BakedGoodsは本当にあなたによって維持されています:)。

5
Kevin