Datenobjekte in Cloud Datastore werden als Entitäten bezeichnet. Eine Entität verfügt über ein oder mehrere benannte Attribute, von denen jedes einen oder mehrere Werte haben kann. Entitäten derselben Art müssen nicht dieselben Attribute haben und die Werte der Entitäten für ein bestimmtes Attribut müssen nicht alle denselben Datentyp haben. Falls erforderlich, kann eine Anwendung derartige Einschränkungen in einem eigenen Datenmodell festlegen und durchsetzen.
Datastore unterstützt viele Datentypen für Attributwerte. Diese umfassen unter anderem:
- Ganzzahlen
- Gleitkommazahlen
- Strings
- Datumsangaben
- Binärdaten
Eine vollständige Liste der Typen finden Sie unter Attribute und Werttypen.
Jede Entität in Datastore hat einen Schlüssel, der sie eindeutig identifiziert. Der Schlüssel besteht aus den folgenden Komponenten:
- Namespace der Entität, der die Mehrinstanzenfähigkeit ermöglicht
- Die Art der Entität, mit der sie für Datastore-Abfragen kategorisiert wird
- Kennung für die einzelne Entität, entweder
- ein Schlüsselnamen-String
- eine ganzzahlige numerische ID
- Optionaler Ancestor-Pfad zur Entität innerhalb der Datastore-Hierarchie
Eine Anwendung kann eine einzelne Entität mithilfe des Entitätsschlüssels aus Datastore abrufen oder eine bzw. mehrere Entitäten mit einer Abfrage ermitteln, die auf den Schlüsseln oder Attributwerten der Entitäten basiert.
Das Go App Engine SDK enthält ein Paket, mit dem Datastore-Entitäten als Go-Strukturen dargestellt und in Datastore gespeichert und abgerufen werden können.
Datastore selbst erzwingt keine Einschränkungen für die Struktur der Entitäten, beispielsweise ob ein bestimmtes Attribut einen Wert eines bestimmten Typs hat. Diese Aufgabe bleibt der Anwendung überlassen.
Arten und Kennungen
Jede Datastore-Entität ist von einer bestimmten Art. Mit dieser kann die Entität für Abfragen kategorisiert werden. In einer Personalanwendung kann beispielsweise jeder Mitarbeiter eines Unternehmens mit einer Entität der Art Employee
dargestellt werden. In der Go Datastore API geben Sie die Art einer Entität an, wenn Sie einen datastore.Key erstellen. Alle Artnamen, die mit zwei Unterstrichen (__
) beginnen, sind reserviert und dürfen nicht verwendet werden.
Der folgende Beispielcode erstellt eine Entität der Art Employee
, gibt ihre Attributwerte an und speichert die Entität in Datastore:
Mit dem Typ Employee
werden vier Felder für das Datenmodell deklariert: FirstName
, LastName
, HireDate
und AttendedHRTraining
.
Neben einem Typ verfügt jede Entität über eine Kennung, die beim Erstellen der Entität zugewiesen wird. Weil sie zum Schlüssel der Entität gehört, ist die Kennung dauerhaft mit der Entität verknüpft und kann nicht geändert werden. Es gibt zwei Möglichkeiten der Zuweisung:
- Die Anwendung kann ihren eigenen Schlüsselnamen-String für die Entität angeben.
- Datastore kann der Entität automatisch eine ganzzahlige numerische ID zuweisen.
Wenn Sie einer Entität einen Schlüsselnamen zuweisen möchten, geben Sie datastore.NewKey
ein nicht leeres stringID
-Argument an:
Wenn Datastore automatisch eine numerische ID zuweisen soll, verwenden Sie ein leeres stringID
-Argument:
Kennungen zuweisen
Datastore kann so konfiguriert werden, dass automatische IDs mithilfe von zwei verschiedenen Richtlinien für automatische IDs generiert werden:
- Die Richtlinie
default
generiert eine zufällige Abfolge von bisher nicht verwendeten IDs, die näherungsweise gleichmäßig verteilt sind. Jede ID kann maximal 16 Dezimalstellen enthalten. - Die Richtlinie
legacy
erstellt eine Abfolge nicht aufeinanderfolgender IDs aus kleineren Ganzzahlen.
Wenn Sie die Entitäts-IDs für den Nutzer anzeigen möchten und/oder deren Reihenfolge wichtig ist, ist eine manuelle Zuordnung die beste Lösung.
Datastore generiert eine zufällige Abfolge von nicht verwendeten IDs, die annähernd gleichmäßig verteilt sind. Jede ID kann maximal 16 Dezimalstellen enthalten.
Ancestor-Pfade
Entitäten in Cloud Datastore sind hierarchisch organisiert, ähnlich der Verzeichnisstruktur eines Dateisystems. Wenn Sie eine Entität erstellen, können Sie optional eine weitere Entität als übergeordnetes Element angeben. Die neue Entität ist dann ein untergeordnetes Element der übergeordneten Entität. Im Gegensatz zu einem Dateisystem muss die übergeordnete Entität nicht tatsächlich vorhanden sein. Eine Entität ohne übergeordnetes Element wird als Stammentität bezeichnet. Die Verknüpfung zwischen einer Entität und ihrer übergeordneten Entität ist dauerhaft und kann nicht geändert werden, nachdem die Entität erstellt wurde. Cloud Datastore weist zwei Entitäten mit derselben übergeordneten Entität oder zwei Stammentitäten (Entitäten ohne übergeordnete Entität) niemals dieselbe numerische ID zu.
Alle übergeordneten Elemente einer Entität werden als ihre Ancestors bezeichnet und alle untergeordneten Entitäten sind ihre Nachfolger. Eine Stammentität und alle ihre Nachfolger gehören zu derselben Entitätengruppe. Die Abfolge der Entitäten, von einer Stammentität über die untergeordneten Elemente bis zu einer bestimmten Entität, bildet den Ancestor-Pfad. Der vollständige Schlüssel, der die Entität identifiziert, besteht aus einer Abfolge von Art/Kennungs-Paaren, die den Ancestor-Pfad angeben und mit dem Paar der Entität selbst enden:
[Person:GreatGrandpa, Person:Grandpa, Person:Dad, Person:Me]
Bei einer Stammentität ist der Ancestor-Pfad leer und der Schlüssel besteht ausschließlich aus der eigenen Art und der eigenen Kennung der Entität:
[Person:GreatGrandpa]
Dieses Konzept wird anhand des folgenden Diagramms veranschaulicht:
Das übergeordnete Element einer Entität wird mithilfe des Arguments parent
auf datastore.NewKey
festgelegt. Der Wert dieses Arguments sollte der Schlüssel der übergeordneten Entität sein. Im folgenden Beispiel wird eine Entität der Art Address
erstellt und eine Employee
-Entität als übergeordnetes Element ausgewiesen:
Transaktionen und Entitätengruppen
Jeder Vorgang zum Erstellen, Aktualisieren und Löschen einer Entität findet im Rahmen einer Transaktion statt. Eine einzelne Transaktion kann eine beliebige Anzahl solcher Vorgänge umfassen. Um die Konsistenz der Daten zu wahren, sorgt die Transaktion dafür, dass entweder alle enthaltenen Vorgänge auf Datastore als Einheit angewendet werden oder überhaupt nicht, sofern einer der Vorgänge fehlgeschlagen ist. Darüber hinaus greifen alle strikt konsistenten Lesevorgänge (Ancestor-Abfragen oder -Abrufe) innerhalb derselben Transaktion auf einen konsistenten Snapshot der Daten zurück.
Wie oben bereits erwähnt besteht eine Entitätengruppe aus einer Reihe von Entitäten, die über einen Ancestor-Pfad mit einem gemeinsamen Stammelement verbunden sind. Die Anordnung von Daten in Entitätengruppen kann einschränken, welche Transaktionen ausgeführt werden können:
- Alle Daten, auf die eine Transaktion zugreift, müssen in maximal 25 Entitätengruppen enthalten sein.
- Wenn Sie Abfragen innerhalb einer Transaktion verwenden möchten, müssen die Daten so in Entitätengruppen angeordnet werden, dass Sie Ancestor-Filter angeben können, die mit den richtigen Daten übereinstimmen.
- Es gibt einen Schreibdurchsatzgrenzwert von ca. einer Transaktion pro Sekunde innerhalb einer einzelnen Entitätengruppe. Diese Begrenzung ist vorhanden, weil Datastore eine synchrone Replikation ohne Master jeder Entitätengruppe über einen breiten geografischen Bereich hinweg durchführt, um hohe Verlässlichkeit und Fehlertoleranz zu ermöglichen.
In vielen Anwendungen kann es akzeptabel sein, für den Abruf einer breiten Ansicht nicht zusammengehöriger Daten Eventual Consistency zu verwenden, also eine entitätengruppenübergreifende Nicht-Ancestor-Abfrage, die gelegentlich etwas veraltete Daten zurückgeben kann. Anschließend wird dann strikte Konsistenz (eine Ancestor-Abfrage oder ein get
einer einzelnen Entität) verwendet, um eine einzelne Gruppe von eng zusammengehörigen Daten anzusehen oder zu bearbeiten. In derartigen Anwendungen ist die Gruppierung von eng zusammengehörigen Daten in Entitätsgruppen im Allgemeinen ein guter Ansatz.
Weitere Informationen finden Sie unter Für strikte Konsistenz strukturieren.
Attribute und Werttypen
Die mit einer Entität verknüpften Datenwerte bestehen aus einem oder mehreren Attributen. Jedes Attribut hat einen Namen und einen oder mehrere Werte. Ein Attribut kann Werte mit mehr als einem Typ haben und zwei Entitäten können Werte unterschiedlichen Typs für dasselbe Attribut haben. Attribute können indexiert oder nicht indexiert sein. Abfragen, die nach einem Attribut A sortieren oder filtern, ignorieren Entitäten, bei denen A nicht indexiert ist. Eine Entität kann höchstens 20.000 indexierte Attribute haben.
Die folgenden Werttypen werden unterstützt:
Werttyp | Go-Typ(en) | Sortierreihenfolge | Hinweise |
---|---|---|---|
Ganzzahl | int int8 int16 int32 int64 |
Numerisch | 64-Bit-Ganzzahl, signiert |
Gleitkommazahl | float32 float64 |
Numerisch | 64 Bit mit doppelter Genauigkeit, IEEE 754 |
Boolesch | bool |
false <true |
|
String (kurz) | string |
Unicode |
Bis zu 1.500 Byte. Werte, die länger als 1.500 Byte sind, führen zu einem Fehler in der Laufzeit. |
String (lang) | string (mit noindex ) |
Keine | Bis zu 1 Megabyte Nicht indexiert |
Bytesegment (kurz) | datastore.ByteString |
Bytereihenfolge | Bis zu 1.500 Byte. Werte, die länger als 1.500 Byte sind, führen zu einem Fehler in der Laufzeit. |
Bytesegment (lang) | []byte |
Keine | Bis zu 1 Megabyte Nicht indexiert |
Datum und Uhrzeit | time.Time |
Chronologisch | |
Geografischer Punkt | appengine.GeoPoint |
Nach Breitengrad, dann nach Längengrad |
|
Datastore-Schlüssel | *datastore.Key |
Nach Pfadelementen (Art, Kennung, Art, Kennung...) |
|
Blobstore-Schlüssel | appengine.BlobKey |
Bytereihenfolge |
Sie können auch struct
oder slice
verwenden, um Attribute zusammenzufassen. Weitere Informationen finden Sie in der Referenz zu Datastore.
Wenn eine Abfrage ein Attribut mit Werten verschiedener Typen enthält, verwendet Datastore eine deterministische Sortierung anhand der internen Darstellungen:
- Nullwerte
- Festkommazahlen
- Ganzzahlen
- Datums- und Uhrzeitwerte
- Boolesche Werte
- Bytesequenzen
- Bytesegmente (kurz)
- Unicode-String
- Blobstore-Schlüssel
- Gleitkommazahlen
- Geografische Punkte
- Datastore-Schlüssel
Da lange Bytesegmente und lange Strings nicht indexiert werden, wird für sie keine Reihenfolge definiert.
Mit Entitäten arbeiten
Anwendungen können mit der Datastore API Entitäten erstellen, abrufen, aktualisieren und löschen. Wenn die Anwendung den vollständigen Schlüssel für eine Entität kennt (oder ihn aus dem übergeordneten Schlüssel, der Art und der Kennung ableiten kann), kann sie mit dem Schlüssel direkt mit der Entität arbeiten. Eine Anwendung kann den Schlüssel einer Entität auch als Ergebnis einer Datastore-Abfrage abrufen. Weitere Informationen finden Sie unter Datastore-Abfragen.
Entität erstellen
Zum Erstellen einer neuen Entität in Go müssen Sie eine Instanz eines Go-Struct-Objekts anlegen, Werte für die zugehörigen Felder festlegen und die Entität mit datastore.Put
in Datastore speichern. Nur mit einem Großbuchstaben beginnende exportierte Felder werden in Datastore gespeichert. Sie können den Schlüsselnamen der Entität durch Übergabe eines nicht leeren stringID
-Arguments an datastore.NewKey
angeben:
Wenn Sie einen leeren Schlüsselnamen bereitstellen oder datastore.NewIncompleteKey
verwenden, generiert Datastore automatisch eine numerische ID für den Schlüssel der Entität:
Entität abrufen
Wenn Sie eine Entität mit einem bestimmten Schlüssel abrufen möchten, übergeben Sie den *datastore.Key
als Argument an die datastore.Get
-Funktion. Sie können den *datastore.Key
mit der Funktion datastore.NewKey
generieren.
datastore.Get
füllt eine Instanz des entsprechenden Go-STRUCTs mit Werten.
Entität aktualisieren
Zum Aktualisieren einer vorhandenen Entität ändern Sie die Attribute der Struktur und rufen anschließend datastore.Put
. Die Daten überschreiben die vorhandene Entität. Bei jedem Aufruf von datastore.Put
wird das ganze Objekt an Datastore gesendet.
Entität löschen
Sie können eine Entität unter Angabe ihres Schlüssels mit der Funktion datastore.Delete
löschen.
Batchvorgänge
datastore.Put
, datastore.Get
und
datastore.Delete
haben mehrere Varianten: datastore.PutMulti
, datastore.GetMulti
und
datastore.DeleteMulti
.
Sie ermöglichen die Verarbeitung mehrerer Entitäten in einem einzigen Datastore-Aufruf:
Die Durchführung von Aktionen als Batchvorgänge hat keine Auswirkungen auf Ihre Kosten. Jeder Schlüssel in einem Batchvorgang wird unabhängig davon in Rechnung gestellt, ob der Schlüssel vorhanden ist oder nicht. Die Größe der Entitäten in einem Vorgang wirkt sich nicht auf die Kosten aus.
.