Datastore 中的資料物件稱為「實體」。實體有一或多個命名的「屬性」,每個屬性可以有一或多個值。相同種類的實體不需要具有相同屬性,而實體的特定屬性值並不全都需要屬於相同的資料類型 (如有必要,應用程式可在本身的資料模型建立及強制執行這類限制)。
Datastore 支援各種屬性值的資料類型。其中包括:
- 整數
- 浮點數
- 字串
- 日期
- 二進位資料
如需這些類型的完整清單,請參閱屬性和值類型一節。
Datastore 中的每個實體都有專門用來識別該實體的「金鑰」。索引鍵由下列元件組成:
- 實體的「命名空間」,可允許多租戶架構
- 實體的類型,可將實體分類以便進行 Datastore 查詢
- 個別實體的ID,可以是以下兩者之一:
- 「索引鍵名稱」字串
- 整數「數字 ID」
- 選用的祖系路徑,可將實體置於 Datastore 階層之中
應用程式可使用實體的索引鍵從 Datastore 擷取個別實體,或依據實體的索引鍵或屬性值發出查詢,以擷取一或多個實體。
Go App Engine SDK 包含套件,可將 Datastore 實體表示為 Go 結構體,並在 Datastore 中儲存及擷取這些實體。
Datastore 本身不會對實體結構強制執行任何限制,例如特定屬性是否具有特定類型的值;這項工作是由應用程式負責。
種類及 ID
每個 Datastore 實體都屬於特定「種類」,可將實體分門別類,方便查詢。舉例來說,人力資源應用程式可以使用屬於 Employee
種類的實體來代表公司的每位員工。在 Go Datastore API 中,您可以在建立 datastore.Key 時指定實體的類型。以兩條底線 (__
) 開頭的種類名稱均為保留名稱,不得使用。
以下範例示範了如何建立 Employee
種類的實體、填入屬性值,並將其儲存至 Datastore:
Employee
類型會為資料模型宣告四個欄位:FirstName
、LastName
、HireDate
和 AttendedHRTraining
。
除了種類以外,建立每個實體時還會指派實體的「ID」。因為 ID 屬於實體索引鍵的一部分,所以會與實體永久關聯,且無法變更。ID 可利用兩種方式指派:
- 您的應用程式可以指定自身的實體「索引鍵名稱」字串。
- 您可以讓 Datastore 自動指派整數的「數字 ID」給實體。
如要指派鍵名稱給實體,請將非空白的 stringID
引數提供至 datastore.NewKey
:
如要讓 Datastore 自動指派數字 ID,請使用空白的 stringID
引數:
指派 ID
Datastore 可使用兩種不同的自動 ID 政策設定自動產生 ID:
default
政策可產生隨機順序的未使用 ID,近乎均勻分佈。每個 ID 最長可達 16 個十進位數字。legacy
政策可建立一系列非連續的較小整數 ID。
如果您要向使用者顯示實體 ID,並/或依據其順序顯示,最理想的方式就是使用手動分配。
Datastore 會產生順序隨機且近乎均勻分佈的未使用 ID。每個 ID 最長可達 16 個十進位數字。
祖系路徑
Cloud Datastore 中的實體會形成階層結構空間,與檔案系統的目錄結構相似。建立實體時,可選擇將其他實體指定為「父項」;新實體則為父系實體的「子項」(請注意,不同於檔案系統,父項實體不需要實際存在)。沒有父項的實體則是「根實體」。實體與父項實體之間具有永久關聯性,一旦實體建立後就無法變更。Cloud Datastore 絕對不會將相同的數字 ID 指派給父項相同的兩個實體,也不會指派給兩個根實體 (即沒有父項的實體)。
實體的父項、父項的父項等以此類推,全都是這個實體的「祖系」;實體的子項、子項的子項等等,則都是其「子系」。根實體及其所有子系都屬於相同的「實體群組」。從根實體開始,再從父項到子項,最後到指定實體的實體序列,即構成該實體的「祖系路徑」。識別實體的完整索引鍵,包含連串種類-ID 組合序列,其中指定了實體的祖系路徑,最後則以該實體本身的種類-ID 組合做為結尾:
[Person:GreatGrandpa, Person:Grandpa, Person:Dad, Person:Me]
根實體的祖系路徑是空白路徑,其金鑰只包含實體本身的種類與 ID。
[Person:GreatGrandpa]
本概念以下圖說明:
如要指定實體的父項,請將 parent
引數用於 datastore.NewKey
。此指數值應為父項實體金鑰。以下範例會建立 Address
種類的實體,並指定 Employee
實體做為其父項:
交易和實體群組
每次嘗試建立、更新或刪除實體時,都是在交易的背景下進行。單一交易可包含的前述作業數量不受限制。為了維持資料一致性,交易一定會使其中包含的變動整組適用於 Datastore,其中如有任何變動失敗,則整組變動均不適用。此外,在相同交易內執行的所有同步一致性讀取作業 (祖系查詢或「get」) 將出現一致的資料快照。
如前所述,實體群組是一組實體,透過祖系連接至共同根元素。將資料組織為實體群組,可限制執行的交易:
- 一項交易所存取的所有資料,最多只能存在於 25 個實體群組中。
- 如果您想在交易中使用查詢,必須將資料歸納成實體群組,才可指定能夠比對出正確資料的祖系篩選條件。
- 單一實體群組的寫入總處理量大約是每秒一次交易。之所以會有這項限制,原因在於 Datastore 會針對橫跨大範圍地理區域的每個實體執行免主機的同步複製作業,以利發揮高度的可靠性和容錯能力。
在許多應用程式中,當您想取得不相關資料的廣泛檢視畫面時,可以使用最終一致性 (即跨多個實體群組的非祖系查詢,有時可能會傳回稍微過時的資料),然後在查看或編輯一組高度相關資料時,使用同步一致性 (祖系查詢或單一實體的 get
)。在此類應用程式中,針對各組高度相關的資料使用獨立實體群組,通常會有不錯的效果。詳情請參閱「建立同步一致性結構」。
屬性和值類型
與實體相關聯的資料值由一或多個「屬性」組成。每個屬性都有一個名稱及一或多個值。一個屬性可能會有多個類型的值,而兩個實體的相同屬性可能會有不同類型的值。屬性可能已建立索引或未建立索引 (排序或篩選屬性「P」的查詢將忽略「P」未建立索引的實體)。一個實體最多可有 20,000 個已建立索引的屬性。
值類型 | Go 類型 | 排序順序 | 附註 |
---|---|---|---|
整數 | int int8 int16 int32 int64 |
數字 | 64 位元整數,帶正負號 |
浮點數 | float32 float64 |
數字 | 64 位元雙精度, IEEE 754 |
布林值 | bool |
false <true |
|
字串 (短) | string |
Unicode |
最多 1500 個位元組。超過 1500 位元組的值會在執行階段造成錯誤。 |
字串 (長) | string (含 noindex ) |
無 | 最多 1 MB 不會建立索引 |
位元組切割 (短) | datastore.ByteString |
位元組順序 | 最多 1500 個位元組。超過 1500 位元組的值會在執行階段造成錯誤。 |
位元組切割 (長) | []byte |
無 | 最多 1 MB 不會建立索引 |
日期與時間 | time.Time |
依時間順序 | |
地理點 | appengine.GeoPoint |
依照緯度、 然後經度 |
|
Datastore 索引鍵 | *datastore.Key |
依路徑元素 (種類、ID、 種類、ID...) |
|
Blobstore 金鑰 | appengine.BlobKey |
位元組順序 |
您也可以使用 struct
或 slice
匯總屬性。詳情請參閱 Datastore 參考資料。
當查詢的屬性具有混合類型的值時,Datastore 會根據內部表示法使用確定性排序:
- 空值
- 固定點數
- 整數
- 日期和時間
- 布林值
- 位元組序列
- 位元組切割 (短)
- Unicode 字串
- Blobstore 索引鍵
- 浮點數
- 地理點
- Datastore 索引鍵
由於長位元組切割和長字串不會建立索引,因此未定義排序。
處理實體
應用程式可使用 Datastore API 建立、擷取、更新及刪除實體。如果應用程式知道實體的完整索引鍵 (或是可從父系索引鍵、種類和 ID 中取得),即可在該實體上使用索引鍵直接作業。應用程式也可以透過 Datastore 查詢取得實體索引鍵,詳情請參閱「Datastore 查詢」頁面。
建立實體
在 Go 中,您可以透過下列方式建立新的實體:建立 Go 結構的執行個體、填入其欄位,並呼叫 datastore.Put
將實體儲存至 Datastore。只有匯出的欄位 (以大寫字母開頭) 會儲存至 Datastore。您可以將非空白的 stringID
引數傳送至 datastore.NewKey
,藉此為實體指定索引鍵名稱:
如果您提供空白的金鑰名稱,或使用 datastore.NewIncompleteKey
,Datastore 會自動為實體的金鑰產生數字 ID:
擷取實體
如要擷取以特定索引鍵識別的實體,請將 *datastore.Key
做為引數傳送至 datastore.Get
函式。您可以使用 datastore.NewKey
函式產生 *datastore.Key
。
datastore.Get
會填入適當 Go 結構的例項。
更新實體
如要更新現有實體,請修改結構的屬性,然後呼叫 datastore.Put
。此資料會覆寫現有實體。每次呼叫 datastore.Put
時,系統會將整個物件傳送至 Datastore。
刪除實體
只要有實體的金鑰,就可以透過 datastore.Delete
函式刪除該實體:
批次作業
datastore.Put
、datastore.Get
和 datastore.Delete
有名為 datastore.PutMulti
、datastore.GetMulti
和 datastore.DeleteMulti
的大量變化版本。這些方法可在單一 Datastore 呼叫中對多個實體執行動作:
批次作業不會影響費用。無論每個索引鍵存在與否,您都必須為批次作業中的每一個索引鍵付費。作業中實體的大小不會影響費用。