お気に入り | 日本語 | ログイン

キーとエンティティ グループ

データストア内のエンティティはすべて、アプリケーション全体のエンティティに対して一意の「キー」を持っています。キーにはいくつかのコンポーネントがあります。エンティティ間の親子関係を記述する「パス」、エンティティの「種類」、そしてアプリケーションによってエンティティに割り当てられた「名前」またはデータストアによって割り当てられた数値「ID」です。

種類、名前、ID

すべてのエンティティは、クエリによって返されるエンティティのコレクションである、特定の種類に属しています。テーブルの行とは異なり、2 つの同じ種類のエンティティは同じプロパティを持っている必要がありません。ただし、アプリケーションでデータ モデルにそのような制限を設定することは可能です。Datastore API は、Model(または Expando)のサブクラス名を種類名として使用します。

たとえば、このクラスは「Story」という名前の種類をモデルに定義します。

class Story(db.Model):
  title = db.StringProperty()
  author = db.StringProperty()

すべてのエンティティは識別子を持っています。アプリケーションは、インスタンス コンストラクタに key_name 引数(str 値)を指定して、キーに使用するためにアプリケーション自身の識別子を割り当てることができます。

s = Story(key_name="xzy123")

key_name は Unicode 文字列(str 値が ASCII テキストに変換されたもの)として格納されます。key_name は先頭に数字を持つことができません。また、__*__(2 つのアンダースコアで始まり、終了する)の形式を取ることもできません。ユーザーのアプリケーションは、ユーザーが送信したデータをデータストア エンティティ キー名(メール アドレスなど)として使用するには、既知の文字列を前に付けるなどの方法で、その値を最初にサニタイズして、上記の要件を満たす必要があります。

key_name が指定されていない場合、エンティティが初めてデータストアに格納されるときに数値 ID が割り当てられます。

s2 = Story()    # s2 does not have a name or an ID.
s2.put()        # s2 is given an ID by the datastore.

エンティティが作成されると、その ID または名前を変更することができません。

ヒント: キー名と ID はプロパティ値ではありません。ただし、特殊なプロパティ名 __key__ を参照することで、キーについて限定的なクエリを実行できます。すべてのエンティティに同じ種類と親がある場合、並び替え順序をキー名または ID に適用できます。キーに対するクエリ をご覧ください。

エンティティ グループ、祖先とパス

すべてのエンティティは、一度のトランザクションで操作できる、1 つ以上のエンティティのセットである、「エンティティ グループ」に属しています。App Engine はエンティティ グループの関係に基づいて、複数のエンティティを分散ネットワークの同じ場所に格納します。トランザクションがエンティティ グループのデータストア オペレーションを設定し、すべてのオペレーションはグループとして適用されます。トランザクションが失敗した場合は、まったく適用されません。

アプリケーションがエンティティを作成する際、Model コンストラクタの parent 引数を使用して、別のエンティティを新しいエンティティの「親」として割り当てることができます。新しいエンティティに親を割り当てることは、新しいエンティティを親エンティティと同じグループに入れることになります。

親を持たないエンティティは、「ルート」 エンティティとなります。別のエンティティの親であるエンティティも、親を持つことができます。あるエンティティからルートまでの親エンティティの連鎖は、エンティティの「パス」となり、パスのメンバーはエンティティの「祖先」となります。エンティティの親はエンティティの作成時に定義され、その後変更することはできません。

指定されたルート エンティティを祖先とするエンティティはすべて、同じエンティティ グループとなります。同じグループ内のエンティティはすべて、同じデータストア ノードに格納されます。1 回のトランザクションで、1 つのグループ内にある複数のエンティティを修正したり、新しいエンティティの親をグループ内に存在させることでそのエンティティをグループに追加することができます。

トランザクションに関する詳しい情報は、トランザクションをご覧ください。

別のエンティティの祖先であるエンティティが削除された場合でも、子孫エンティティは削除されません。子孫エンティティは、完全な Key またはパスを使用してアクセスすることが可能です。

先に親エンティティを作成しないで、祖先パスを持つエンティティを作成することもできます。そのためには、種類とキー名を使用して祖先用の Key を作成し、それを新しいエンティティの親として使用します。パスのルートが実際のエンティティを表すかどうかには関係なく、同じルート祖先を持つエンティティはすべて同じエンティティ グループに属します。

エンティティ グループを使用するためのヒント:

  • トランザクションに必要なときにだけ、エンティティ グループを使用します。その他のエンティティ間の関係には、ReferenceProperty プロパティと、クエリで使用できる Key 値を使用します。
  • アプリケーションにエンティティ グループが多ければ多い(つまり、ルート エンティティが多い)ほど、データストアはより効率的にデータストア ノード全体にエンティティを分散することができます。分散効率が向上すると、データの作成と更新のパフォーマンスも向上します。また、複数のユーザーが同時に同じエンティティ グループのエンティティを更新しようとすると、一部のユーザーはトランザクションの再試行が必要になったり、場合によっては変更に失敗することがあります。アプリケーションのすべてのエンティティを 1 つのルートの下に置かないでください。
  • 経験則では、エンティティ グループのサイズは 1 人のユーザーのデータ量に相当するかそれ以下のサイズがよいようです。
  • エンティティ グループはクエリの速度にはあまり影響しません。

パスとキーの一意性

パス、種類、名前や数値 ID を含んだエンティティの完全なキーは、一意であり、エンティティに固有のものです。完全なキーはエンティティがデータストアに作成されたときに割り当てられ、どの部分も変更することができません。

個別の 2 つのエンティティのキーは、少なくとも一部が異なりさえすれば、類似した部分があっても構いません。たとえば、親が違っていれば、2 つのエンティティが同じ種類と名前を持つことができます。同様に、2 つのエンティティが同じ名前と親を持っていても(または親なしでも)、種類が異なっていれば構いません。

アプリケーションは、エンティティを作成した順番に数字を増やして割り当てる数値 ID に依存しないようにしてください。この方法は一般的ですが、保証はされません。