目次

Datastoreを使った開発をするにあたって、Datastoreを理解するためのメモです。

随時更新します。

Datastore | Google Cloud

RDB との比較

概念 Datastore RDB
カテゴリ Kind Table
1つのオブジェクト Entity Row
各データ Property Field
ユニークなID Key Primary Key

Kind -> Entity -> Propertyという親子関係のような感じ。

データ整理

Google Cloud Datastoreでのデータ整理の考え方

Google Cloud Datastore のような非リレーショナル データベースにおけるデータのモデリングや保存には、固有の難しさがあります。結合や正規化など、リレーショナル データベースの有益な機能の多くは、非リレーショナル データについては、スケーラビリティに欠けるという理由で適用されません。リレーショナル データベースを「オブジェクトと関係」としてとらえるという一般的なアプローチも、非リレーショナル データベースに当てはめるのは困難です。

次の例でデータをパスとして整理する方法を考える

例 : マルチユーザーブログ

RDBの場合

User

id username name
1 tonystark Tony Stark
2 dianaprince Diana Prince

Post

id user_id content
1 1 Hello, world!
2 2 Another post

特定のユーザが書き込んだすべての投稿を検索したい場合

SELECT * FROM Posts WHERE user_id = {user_id}

でOK

Datastore の場合

User と Post の2つの Kind を持つようにすると、次のようになる。

Key Data
(Post, 1) {“user”: Key(User, tonystark), “content”: “Hello, World!”}
(Post, 2) {“user”: Key(User, dianaprince), “content”: “Another post”}
(User, tonystark) {“name”: “Tony Stark”}
(User, dianaprince) {“name”: “Diana Prince”}

Post Kind 全体を username でフィルタリングすることで、特定のユーザーが書き込んだ全ての投稿を検索できる。

datastore.Query(kind='Post', filters=[('user', '=', Key('User', username))])

このクエリは結果整合性をもつ。

ファイルシステム

非リレーショナルデータをテーブルやキーの観点からではなく、ファイルシステムとして考える

/1.post
/2.post
/tonystark.user
/dianaprince.user

このデータは、ユーザー別にグループ化して再整理できる

/tonystark.user
  /1.post
/dianaprince.user
  /2.post
Key Data
(User, tonystark) {“name”: “Tony Stark”}
(User, tonystark, Post, 1) {“content”: “Hello, World!”}
(User, dianaprince) {“name”: “Diana Prince”}
(User, dianaprince, Post, 2) {“content”: “Another post”}

投稿をユーザー別に整理すると、エンティティ グループが作成されます。その中にはユーザーのプロフィールとすべての投稿が含まれます。Cloud Datastore では、1つのエンティティ グループに対するクエリは強い整合性を持ちます。このため、ユーザーは投稿を作成すると、すぐに見ることができます。祖先をキーに指定してクエリを行うことも可能です。

datastore.Query(kind='Post', ancestor=Key('User', username))

ユーザーのプロフィールと投稿を 1 つのエンティティグループにまとめると、整合性と書き込みスループットがトレードオフになる。

エンティティグループ

エンティティグループは、1 つのルートエンティティと、その子エンティティやそれを継承するエンティティから構成される階層。

エンティティグループを作成するには、祖先パス、つまり子キーの前に一連の親キーをつなげて指定する。

エンティティ グループの概念図
(https://cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore?hl=ja#h.3loc7ynqbw6i)

この図では、キー「ateam」を持つルートエンティティには、キー「ateam/098745」とキー「ateam/098746」を持つ 2つの子エンティティがある。

エンティティグループ内では、次の特性が保証される。 - 強整合性 - トランザクション性 - ローカル性

エンティティグループと祖先クエリの制限

エンティティグループと祖先クエリを使用する方法は、次の2つの問題がある

  1. 各エンティティ グループの書き込みは、1秒間に1回の更新
  2. エンティティの作成後にエンティティグループの関係を変更できない

Ref.