私はWebアプリケーションのオフライン機能についての論文を書いています。私の仕事は、サーバー側のリレーショナルデータベースとクライアントとサーバー間のAjax/JSONトラフィックを備えたWebアプリケーションを介したオフラインストレージの可能性を示すことです。私の最初の実装では、localStorageを使用したアプローチを使用し、リクエストURLをキーとして各Ajax応答を値として保存しました。アプリは問題なく動作します。ただし、次のステップでは、クライアント側のデータベースを使用して、より高度なバージョンを実装したいと思います(つまり、論文で必要です)。サーバーはリレーショナルデータベースを維持しているため、WebSQLデータベースが直感的な選択でした。しかし、ご存知のように、この標準は廃止されており、将来が不透明なテクノロジーは使用したくありません。したがって、IndexedDBを使用してクライアント側のデータベースロジックを実装したいと思います。不運にも、
私のタスクはかなり単純なようです 。IndexedDBを使用してクライアントにサーバー側データベースを実装し、サーバーから一度フェッチされたすべてのデータを複製します。これをはるかに簡単にしない問題は次のとおりです。
- サーバー側のデータベースはリレーショナルであり、IndexedDBは(多かれ少なかれ)オブジェクト指向です
- クライアント側とサーバー側のデータベースを同期する直感的な方法はありません
- サーバー上で外部キーとJOINを使用して実装されるIndexedDBの関係を直感的に実装する方法はありません。
今、私は実装を開始することを本当に恐れている概念を念頭に置いています。サーバーデータベース内のすべてのテーブルにオブジェクトストアを作成し、さまざまなオブジェクトストア内のリレーションオブジェクトを手動でプログラムすることを考えました。要するに、大学のコースを管理する私のアプリケーションでは、7つのオブジェクトストアがあります。
サーバーからのJSON応答の例で私のアイデアを示したいと思います(/*これらはコメントです*/):
{ "course": { /* course object */
"id":1,
"lecturer": { "id":"1", /* lecturer object with many attributes */ },
"semester": { "id":"1", /* semester object with many attributes */ },
/* more references and attributes */
}}
IndexedDBを使用してデータを格納するアルゴリズムは、オブジェクトストアに適用される各オブジェクトを適切なオブジェクトストアに格納し、オブジェクトをこれらのオブジェクトへの参照に置き換えます。たとえば、上記のコースオブジェクトは、オブジェクトストア'course'では次のようになります。
{ "course": { /* course object */
"id":1,
"lecturer":
{ "reference": { /* reference to the lecturer in the object store 'lecturer' */
"objectstore":"lecturer",
"id":"1" }
},
"semester":
{ "reference": { /* reference to the semester in the object store 'semester' */
"objectstore":"semester",
"id":"1" }
}
/* more references and attributes */
}}
IndexedDBを使用してデータを取得するアルゴリズムは、次のようになります(再帰パターンを漠然と念頭に置いています)。
Retrieve the course object with id=1 from the object store 'course'
For each reference object in the retrieved course object, do
Retrieve the object with id=reference.id from the object store reference.objectstore
Replace the reference object with the retrieved object
特にIndexedDBの非同期性のために、この実装が非常に面倒であることは明らかです。また、コースオブジェクトを取得するためだけにデータベースに対してさまざまなトランザクションが発生し、パフォーマンスが大幅に低下します(とにかく、IndexedDBトランザクションのパフォーマンスがどのようになるかはわかりません)。
どうすればこれをより良く、より簡単に行うことができますか?
私はすでに同様の問題を表すこれらのスレッドを見ました:link1、link2。これらには、これ以上簡単な解決策はありません。さらに、いくつかの理由から、IndexedDBラッパーフレームワークの使用は避けたいと思います。
また、自分の問題についてIndexedDBで完全に間違った方向に進んでいることも想像できます。
編集:
最終的に、IndexedDBのオブジェクト自体に参照を格納するというアプローチを追求することになりました。これにより、参照が多い大量のデータの場合に、パフォーマンスの問題が発生する可能性があります。ただし、賢く使用すれば、ほとんどの場合、膨大な量の反復とデータベースヒットを回避でき、複雑なデータベーススキーマをメモリまたはIndexedDB自体に格納する必要はありません。
一般的に言って、私はIndexedDBをスキーマレスデータベースとして動的でまっすぐなアイデアを何らかの方法で誤解しているという印象を受けます。しかし、いずれにせよ、私はすべてをJavaScriptで実装しました。それは正常に機能し、矛盾が発生する可能性はありません。