GAE/Go的数据存储备忘录
GAE/Go 数据存储的备忘录
这是关于GAE标准的NoSQL存储Datastore的个人备忘录。
*本文基本上是官方文档的复制。
实体
实体是什么?
-
- キーに関連付けられたDatastoreの保存の際の基本単位
エンティティはユニーク識別子である キー を持つ
エンティティはオプションとして親エンティティを持てる
よってエンティティは全体として、ファイルシステムのような階層化構造となる
实体的键是什么?
-
- 以下のいずれかの要素からなる。
文字列のアプリケーションID
エンティティタイプ(文字列のカインド)
数値(int64)キー
文字列(string)キー
文字列のキーはエンティティ名, キー名とも呼ばれる
親キー(オプション)
string, int64 のゼロ値のキー
インコプリートキーと呼ばれる
保存されたどのエンティティも参照していない状態を表す
インコプリートキーのエンティティをDatastoreに保存すると自動でユニークなキーが生成されて保存される
神明通過
-
- エンティティ作成時、オプションで別のエンティティを「親」として設定できる
このとき親エンティティは実際に存在していなくてもOK
エンティティの親子関係は作成後の変更はできない
一度親を設定したら変更できないし、あとから親を設定することもできない
ルートエンティティから親子関係を辿って対象のエンティティまでの連なりを祖先パスという
实体群组是什么?
-
- 親のないエンティティ を rootエンティティと呼ぶ
同じ祖先からたどるエンティティは同じエンティティグループに属する
つまり、ルートエンティティ以下の全てのエンティティのこと
同じ祖先のエンティティのキーは、グループの親キーとなり、そのエンティティグループを表す。
エンティティグループに対するクエリを ancestor queries と呼ぶ
親キー対して発行する
エンティティグループは 一貫性とトランザクションのユニット
常に最新の結果を返せる。
複数のエンティティグループにまたぐクエリは、古い状態の値を返すことがある
Eventual Consistency(結果整合性)というやつ
1つのエンティティグループにまとめる(同じ祖先を持つ)と常に最新のデータを取得できる
Strong Consistency(強い整合性)というやつ
制約として、同エンティティグループには、1秒1件しか書き込めない
memcacheサービスなどで軽減は可能かもしれない
システムから割り当てられる ID値はエンティティグループに対して一意になる
实体的内容
-
- フィールド名は大文字/小文字を区別する
-
- 通常は構造体のポインタ
PropertyLoadSaver インターフェースを実装した任意の型でもOK
财产加载和保存接口
-
- エンティティの内容は PropertyLoadSaverインターフェースを実装した任意の型で表せる。
構造体のポインタである必要はない
Load はコンテンツの読み込み時, Save は保存時に呼び出される
实施范例
// 以下の CustomPropsExample はエンティティのプロパティとして使用可能
// 通常の埋め込み構造体より機能が追加されている(Sumの計算)
type CustomPropsExample struct {
I, J int
// Sumはdatastoreには保存されないが, 常に I+J の値となる
Sum int `datastore:"-"`
}
func (x *CustomPropsExample) Load(ps []datastore.Property) error {
// I, J を通常通り Load する
if err := datastore.LoadStruct(x, ps); err != nil {
return err
}
// Sumフィールドを埋める
x.Sum = x.I + x.J
return nil
}
func (x *CustomPropsExample) Save() ([]datastore.Property, error) {
// Sumフィールドのバリデーション
if x.Sum != x.I + x.J {
return errors.New("CustomPropsExample has inconsistent sum")
}
// I, J を通常通り Save する. 以下のコードは "return datastore.SaveStruct(x)" と等価だが
// 今回はサンプル提示のため, 手動で行っている
return []datastore.Property{
{
Name: "I",
Value: int64(x.I),
},
{
Name: "J",
Value: int64(x.J),
},
}
}