2

開発中、私は空のデータストアを持っています。オンラインには、何百万ものエンティティを含むデータストアがあります。

開発データストアに(ローカルで)1つの新しいエンティティを配置します(新しいキーを生成します)。次に、エンティティをエクスポートして、オンラインデータストアに配置します(ローカルで生成されたキーを使用)。ローカルで生成されたキーがオンラインデータストア内のエンティティにすでに割り当てられているリスクは何ですか?

または、次のようにローカルでキーを作成することにより、衝突を回避する方が簡単でしょうか。

for (int i = 0; i < data.size(); i++) {
    Key k = KeyFactory.createKey(kind, new Date() + i);
    // continue to creating and inserting entities...
}

ありがとう。

4

4 に答える 4

3

https://developers.google.com/appengine/docs/java/datastore/entitiesから:

高度なアプリケーションでは、キー名の文字列を使用したり、数値IDを自動的に生成したりする代わりに、作成したエンティティに独自の数値IDを手動で割り当てたい場合があります。ただし、データストアが手動の数値IDの1つを別のエンティティに割り当てることを妨げるものは何もないことに注意してください。このような競合を回避する唯一の方法は、DatastoreService.allocateIds()メソッドまたはAsyncDatastoreService.allocateIds()メソッドを使用してアプリケーションにIDのブロックを取得させることです。データストアの自動IDジェネレーターは、これらのメソッドで割り当てられたIDを追跡し、それらを別のエンティティに再利用することを回避するため、競合することなくそのようなIDを安全に使用できます。

すべての数値キーを手動で生成するか(およびそれらが衝突しないように)、を使用する必要がありますallocateIds()。特に、手動で生成したものが、その関数を使用しない限り、既存のキーと衝突しないという保証はありません。生成されたキーIDは、毎回1つずつインクリメントするリレーショナルデータベースの自動インクリメントフィールドとは異なります。

于 2012-05-14T16:52:43.633 に答える
0

エンティティにあるIDの種類によって異なります。それらが整数の場合、それらは小さく、簡単に競合する可能性があります。

Googleがデフォルトで使用しているものとは少し異なるキー形式を作成することをお勧めします。上記の関数は、KeyFactoryが時計の完全な精度を使用している限り(つまり、秒単位で停止しない限り)機能するように見えます。

于 2012-05-14T16:38:35.223 に答える
0

データストアがキーを生成するとき、IDは整数です。文字列をIDとして使用してキーを生成する場合、それらは既存のエンティティを上書きしません。

a.key.id() == 1
b.key.id() == '1'
a.key.id() != b.key.id()
于 2012-05-15T14:47:29.037 に答える
0

適切な解決策を提案できるように、ユースケースに関するもう少し情報を提供する必要があります。たとえば、次のようにdevデータベースにキーを作成できます。

  KeyFactory.createKey(entity, "dev_" + UUID.randomUUID())

もう1つのオプションは、ローカルデータベースからエンティティを取得し、それを開発データベースにPOSTする小さなユーティリティまたはアプリを作成することです。POSTを取得するオンラインサーバーは、新しいエンティティを作成し、キーを除くすべてのプロパティをクライアントから割り当てます。これにより、GAEは新しいキーを自動的に生成します。その後、POST操作への応答として、新しいキーをクライアントに送り返すことができます。

繰り返しになりますが、後でローカルデータベースを更新してオンラインと再同期するかどうかはわかりませんが、更新する場合は、次の同期でエンティティがオンラインで更新されるため、独自のキーを定義する最初のアプローチが機能します。

于 2012-05-15T21:16:16.607 に答える