Dans Datastore, les objets de données sont appelés entités. Une entité est associée à une ou plusieurs propriétés nommées, chacune pouvant avoir une ou plusieurs valeurs. Les entités du même genre n'ont pas besoin d'avoir les mêmes propriétés, et il n'est pas nécessaire que les valeurs d'une entité pour une propriété donnée soient toutes du même type de données. (Si nécessaire, une application peut établir et appliquer de telles restrictions dans son propre modèle de données.)
Datastore est compatible avec divers types de données pour les valeurs de propriété, parmi lesquels :
- Entiers
- Nombres à virgule flottante
- Chaînes
- Dates
- Données binaires
Pour obtenir la liste complète des types, consultez la section Propriétés et types de valeurs.
Chaque entité dans Datastore possède une clé qui l'identifie de manière unique. Cette clé comprend les composants suivants :
- L'espace de noms de l'entité, qui permet de définir l'architecture mutualisée.
- Le genre de l'entité, qui permet de la classer pour les besoins des requêtes Datastore.
- Un identifiant associé à l'entité de manière individuelle, qui peut être :
- Une chaîne de nom de clé
- Un ID numérique sous forme d'entier.
- Un chemin d'ancêtre facultatif localisant l'entité dans la hiérarchie Datastore
Une application peut extraire une entité individuelle de Datastore à l'aide de la clé de l'entité, ou extraire une ou plusieurs entités en émettant une requête basée sur leurs clés ou leurs valeurs de propriétés.
Le SDK App Engine Go inclut un package permettant de représenter les entités Datastore en tant que structures Go, ainsi que de les stocker et de les récupérer dans Datastore.
Datastore lui-même n'applique aucune restriction à la structure des entités pour déterminer, par exemple, si une propriété donnée a une valeur d'un type particulier. Cette tâche revient à l'application.
Genres et identifiants
Chaque entité Datastore est d'un genre particulier, ce qui permet de la classer dans une catégorie pour les besoins des requêtes. Par exemple, une application de ressources humaines peut représenter chaque employé d'une entreprise avec une entité du genre Employee
. Dans l'API Datastore Go, vous spécifiez le genre d'une entité lorsque vous créez une clé datastore.Key. Tous les noms de genre commençant par deux traits de soulignement (__
) sont réservés et ne peuvent pas être employés.
L'exemple suivant crée une entité du genre Employee
, renseigne ses valeurs de propriété et l'enregistre dans Datastore :
Le type Employee
déclare quatre champs pour le modèle de données : FirstName
, LastName
, HireDate
et AttendedHRTraining
.
En plus d'un genre, chaque entité possède un identifiant qui lui est attribué au moment de sa création. Comme il fait partie de la clé de l'entité, l'identifiant est associé de manière permanente à celle-ci et ne peut pas être modifié. Il peut être attribué de deux manières :
- L'application peut spécifier sa propre chaîne de nom de clé pour l'entité.
- Vous pouvez demander à Datastore d'attribuer automatiquement à l'entité un ID numérique sous forme d'entier.
Pour attribuer un nom de clé à une entité, fournissez un argument stringID
non vide à datastore.NewKey
:
Pour que Datastore attribue un ID numérique automatiquement, employez un argument stringID
vide :
Attribuer des identifiants
Datastore peut être configuré de sorte à générer des identifiants automatiques à l'aide de deux règles d'ID automatique différentes :
- La règle
default
génère une séquence aléatoire d'ID inutilisés distribués d'une manière approximativement uniforme. Chaque ID peut comporter jusqu'à 16 chiffres décimaux. - La règle
legacy
crée une séquence d'ID entiers plus petits non consécutifs.
Si vous souhaitez que les ID d'entité soient visibles par l'utilisateur et/ou si vous souhaitez les afficher en fonction de leur ordre, l'allocation manuelle est la meilleure solution.
Datastore génère une séquence aléatoire d'ID inutilisés distribués de manière approximativement uniforme. Chaque ID peut comporter jusqu'à 16 chiffres décimaux.
Chemins d'ancêtre
Dans Cloud Datastore, les entités forment un espace structuré de manière hiérarchique, semblable à la structure de répertoires d'un système de fichiers. Lorsque vous créez une entité, vous pouvez éventuellement en désigner une autre comme son parent. La nouvelle entité est alors un enfant de l'entité parente. Contrairement à ce qui se produit dans un système de fichiers, l'entité parente n'a pas besoin d'exister réellement. Une entité sans parent est une entité racine. L'association entre une entité et son parent est permanente, et elle ne peut plus être modifiée une fois l'entité créée. Cloud Datastore n'attribue jamais le même ID numérique à deux entités ayant le même parent ou à deux entités racines (celles sans parent).
Les ancêtres d'une entité correspondent à son parent, au parent de son parent et ainsi de suite, de manière récursive. Ses descendants sont ses enfants, les enfants de ses enfants, etc. Une entité racine et tous ses descendants appartiennent au même groupe d'entités. La séquence d'entités commençant par une entité racine, puis allant du parent à l'enfant et menant à une entité donnée, constitue le chemin d'ancêtre de cette entité. La clé complète identifiant l'entité consiste en une séquence de paires genre/identifiant, qui spécifie son chemin d'ancêtre et se termine par les valeurs de l'entité elle-même :
[Person:GreatGrandpa, Person:Grandpa, Person:Dad, Person:Me]
Pour une entité racine, le chemin d'ancêtre est vide, et la clé est constituée uniquement du genre et de l'identifiant de l'entité :
[Person:GreatGrandpa]
Le schéma suivant illustre ce concept :
Pour désigner le parent d'une entité, utilisez l'argument parent
pour datastore.NewKey
. La valeur de cet argument doit être la clé de l'entité parente. L'exemple suivant crée une entité du genre Address
et désigne comme parent une entité Employee
:
Transactions et groupes d'entités
Toute tentative de création, de mise à jour ou de suppression d'une entité a lieu dans le cadre d'une transaction. Une même transaction peut inclure un nombre illimité d'opérations de ce type. Pour maintenir la cohérence des données, la transaction garantit que toutes les opérations qu'elle contient sont appliquées à Datastore de manière unitaire ou, en cas d'échec de l'une de ces opérations, qu'aucune d'entre elles n'est appliquée. En outre, toutes les lectures fortement cohérentes (requêtes ascendantes ou opérations "get") effectuées dans la même transaction observent un instantané cohérent des données.
Comme mentionné ci-dessus, un groupe d'entités est un ensemble d'entités connectées par le biais d'un ancêtre à un élément racine commun. L'organisation des données en groupes d'entités peut limiter le nombre de transactions pouvant être effectuées :
- Toutes les données auxquelles accède une transaction doivent être contenues dans 25 groupes d'entités au maximum.
- Si vous souhaitez employer des requêtes dans une transaction, les données doivent être organisées en groupes d'entités de sorte que vous puissiez spécifier des filtres d'ancêtres qui correspondent aux données appropriées.
- Le débit en écriture est limité à environ une transaction par seconde pour un seul groupe d'entités. Cette limite a été définie car Datastore effectue une réplication synchrone sans maître de chaque groupe d'entités sur une vaste zone géographique, afin de fournir une fiabilité et une tolérance aux pannes élevées.
Dans de nombreuses applications, il est acceptable de recourir à la cohérence à terme (à savoir à une requête non ascendante couvrant plusieurs groupes d'entités et pouvant parfois renvoyer des données légèrement obsolètes) lors de l'obtention d'une vue d'ensemble de données non liées, puis de passer à la cohérence forte (requête ascendante ou opération get
d'une seule entité) lors de la visualisation ou de la modification d'un seul ensemble de données étroitement liées. Dans ces applications, il est généralement recommandé d'utiliser un groupe d'entités distinct pour chaque ensemble de données étroitement liées.
Pour en savoir plus, consultez la page Structurer des données pour renforcer la cohérence.
Propriétés et types de valeurs
Les valeurs de données associées à une entité consistent en une ou plusieurs propriétés. Chaque propriété a un nom, et une ou plusieurs valeurs. Une propriété peut avoir des valeurs de plus d'un type, et deux entités peuvent avoir des valeurs de types différents pour la même propriété. Les propriétés peuvent être indexées ou non indexées (les requêtes qui ordonnent ou filtrent une propriété P ignorent les entités pour lesquelles P n'est pas indexée.) Une entité peut avoir 20 000 propriétés indexées au maximum.
Les types de valeurs suivants sont acceptés :
Type de valeur | Type(s) Go | Ordre de tri | Remarques |
---|---|---|---|
Entier | int int8 int16 int32 int64 |
Numérique | Entier de 64 bits, signé |
Nombre à virgule flottante | float32 float64 |
Numérique | Double précision 64 bits, IEEE 754. |
Booléen | bool |
false <true |
|
Chaîne (courte) | string |
Unicode |
Jusqu'à 1 500 octets. Les valeurs supérieures à 1 500 octets génèrent une erreur au moment de l'exécution. |
Chaîne (longue) | string (avec noindex ) |
Aucun | Jusqu'à 1 mégaoctet Non indexé |
Tranche d'octets (courte) | datastore.ByteString |
Ordre des octets | Jusqu'à 1 500 octets. Les valeurs supérieures à 1 500 octets génèrent une erreur au moment de l'exécution. |
Tranche d'octets (longue) | []byte |
Aucun | Jusqu'à 1 mégaoctet Non indexé |
Date et heure | time.Time |
Chronologique | |
Point géographique | appengine.GeoPoint |
En fonction de la latitude, puis de la longitude |
|
Clé Datastore | *datastore.Key |
Par éléments de chemin d'accès (genre, identifiant, genre, identifiant, etc.) |
|
Clé Blobstore | appengine.BlobKey |
Ordre des octets |
Vous pouvez également agréger des propriétés à l'aide d'un élément struct
ou slice
. Pour en savoir plus, consultez la documentation de référence de Datastore.
Lorsqu'une requête implique une propriété avec des valeurs de types mixtes, Datastore utilise un ordre déterministe basé sur les représentations internes :
- Valeurs Null
- Nombres à virgule fixe
- Entiers
- Dates et heures
- Valeurs booléennes
- Séquences d'octets
- Tranches d'octets (courtes)
- Chaîne Unicode
- Clés Blobstore
- Nombres à virgule flottante
- Points géographiques
- Clés Datastore
Étant donné que les tranches d'octets longues et les chaînes longues ne sont pas indexées, aucun tri n'est défini pour celles-ci.
Utiliser des entités
Les applications peuvent utiliser l'API Datastore pour créer, récupérer, mettre à jour et supprimer des entités. Si l'application connaît la clé complète d'une entité (ou si elle peut la déduire de sa clé parente, de son genre et de son identifiant), elle peut s'en servir pour effectuer des opérations directement sur l'entité. Une application peut également obtenir la clé d'une entité à la suite d'une requête Datastore. Pour plus d'informations, consultez la page Requêtes Datastore.
Créer une entité
Dans Go, pour créer une entité, construisez une instance d'une structure Go, renseignez ses champs, puis appelez datastore.Put
pour l'enregistrer dans Datastore. Seuls les champs exportés (commençant par une lettre majuscule) seront enregistrés dans Datastore. Vous pouvez spécifier le nom de clé de l'entité en transmettant un argument stringID
non vide à datastore.NewKey
.
Si vous fournissez un nom de clé vide ou utilisez datastore.NewIncompleteKey
, Datastore génère automatiquement un ID numérique pour la clé de l'entité :
Récupérer une entité
Pour récupérer une entité identifiée par une clé donnée, transmettez l'élément *datastore.Key
en tant qu'argument à la fonction datastore.Get
. Vous pouvez générer l'élément *datastore.Key
à l'aide de la fonction datastore.NewKey
.
datastore.Get
insère une instance de la structure Go appropriée.
Mettre à jour une entité
Pour mettre à jour une entité existante, modifiez les attributs de la structure, puis appelez datastore.Put
. Les données écrasent l'entité existante. L'objet entier est envoyé à Datastore à chaque appel de datastore.Put
.
Supprimer une entité
Selon la clé d'une entité, vous pouvez supprimer l'entité à l'aide de la fonction datastore.Delete
:
Opérations par lot
datastore.Put
, datastore.Get
et datastore.Delete
ont des variantes groupées appelées datastore.PutMulti
, datastore.GetMulti
et datastore.DeleteMulti
.
Elles permettent d'intervenir sur plusieurs entités via un seul appel Datastore :
Les opérations par lot n'entraînent pas de modification des coûts. Vous serez facturé pour chaque clé employée dans ces opérations, que cette clé existe ou non. La taille des entités impliquées dans une opération n'a pas d'incidence sur les coûts.