Os objetos de dados no Datastore são conhecidos como entidades. Uma entidade tem uma ou mais propriedades com nome, cada uma das quais pode ter um ou mais valores. As entidades do mesmo tipo não têm de ter as mesmas propriedades e os valores de uma entidade para uma determinada propriedade não têm de ser todos do mesmo tipo de dados. (Se necessário, uma aplicação pode estabelecer e aplicar essas restrições no seu próprio modelo de dados.)
O Datastore suporta uma variedade de tipos de dados para valores de propriedades. Estas incluem, entre outras:
- Números inteiros
- Números de vírgula flutuante
- Strings
- Datas
- Dados binários
Para ver uma lista completa de tipos, consulte o artigo Propriedades e tipos de valores.
Cada entidade no Datastore tem uma chave que a identifica de forma exclusiva. A chave é composta pelos seguintes componentes:
- O espaço de nomes da entidade, que permite a multilocação
- O tipo da entidade, que a categoriza para efeitos de consultas do Datastore
- Um identificador para a entidade individual, que pode ser
- Uma string de nome da chave
- um ID numérico inteiro
- Um caminho do antepassado opcional que localiza a entidade na hierarquia do Datastore
Uma aplicação pode obter uma entidade individual do Datastore através da chave da entidade ou pode obter uma ou mais entidades emitindo uma consulta com base nas chaves ou nos valores das propriedades das entidades.
O SDK do App Engine Go inclui um pacote para representar entidades do Datastore como estruturas Go e para as armazenar e obter no Datastore.
O Datastore em si não aplica restrições à estrutura das entidades, como se uma determinada propriedade tem um valor de um tipo específico. Esta tarefa é deixada à aplicação.
Tipos e identificadores
Cada entidade do Datastore é de um tipo específico,que categoriza a entidade para fins de consultas: por exemplo, uma aplicação de recursos humanos pode representar cada funcionário de uma empresa com uma entidade do tipo Employee
. Na API Go Datastore, especifica o tipo de uma entidade quando cria um datastore.Key. Todos os nomes de tipos que começam com dois sublinhados (__
) estão reservados e não podem ser usados.
O exemplo seguinte cria uma entidade do tipo Employee
, preenche os respetivos valores de propriedades e guarda-a no Datastore:
O tipo Employee
declara quatro campos para o modelo de dados: FirstName
, LastName
, HireDate
e AttendedHRTraining
.
Além de um tipo, cada entidade tem um identificador, atribuído quando a entidade é criada. Uma vez que faz parte da chave da entidade, o identificador está associado permanentemente à entidade e não pode ser alterado. Pode ser atribuído de duas formas:
- A sua aplicação pode especificar a sua própria string de nome da chave para a entidade.
- Pode fazer com que o Datastore atribua automaticamente à entidade um ID numérico inteiro.
Para atribuir um nome de chave a uma entidade, forneça um argumento stringID
não vazio a datastore.NewKey
:
Para que o Datastore atribua automaticamente um ID numérico, use um argumento stringID
vazio:
Atribuir identificadores
O Datastore pode ser configurado para gerar IDs automáticos através de duas políticas de IDs automáticos diferentes:
- A política
default
gera uma sequência aleatória de IDs não usados que são distribuídos de forma aproximadamente uniforme. Cada ID pode ter até 16 dígitos decimais. - A política
legacy
cria uma sequência de IDs de números inteiros mais pequenos não consecutivos.
Se quiser apresentar os IDs das entidades ao utilizador e/ou depender da respetiva ordem, a melhor opção é usar a atribuição manual.
O Datastore gera uma sequência aleatória de IDs não usados que são distribuídos de forma aproximadamente uniforme. Cada ID pode ter até 16 dígitos decimais.
Caminhos de antecessores
As entidades no Cloud Datastore formam um espaço estruturado hierarquicamente semelhante à estrutura de diretórios de um sistema de ficheiros. Quando cria uma entidade, pode, opcionalmente, designar outra entidade como respetiva principal. A nova entidade é uma secundária da entidade principal (tenha em atenção que, ao contrário de um sistema de ficheiros, a entidade principal não tem de existir efetivamente). Uma entidade sem um elemento principal é uma entidade raiz. A associação entre uma entidade e a respetiva entidade principal é permanente e não pode ser alterada depois de a entidade ser criada. O Cloud Datastore nunca atribui o mesmo ID numérico a duas entidades com o mesmo elemento principal ou a duas entidades raiz (as que não têm um elemento principal).
O principal de uma entidade, o principal do principal e assim sucessivamente, são os seus ancestrais; os seus secundários, os secundários dos secundários e assim sucessivamente, são os seus descendentes. Uma entidade raiz e todos os respetivos descendentes pertencem ao mesmo grupo de entidades. A sequência de entidades que começa com uma entidade de raiz e prossegue do elemento principal para o elemento secundário, conduzindo a uma determinada entidade, constitui o caminho do antepassado dessa entidade. A chave completa que identifica a entidade consiste numa sequência de pares de tipo-identificador que especificam o respetivo caminho de antepassados e terminam com os da própria entidade:
[Person:GreatGrandpa, Person:Grandpa, Person:Dad, Person:Me]
Para uma entidade raiz, o caminho de antepassados está vazio e a chave consiste apenas no tipo e no identificador da própria entidade:
[Person:GreatGrandpa]
Este conceito é ilustrado pelo diagrama seguinte:
Para designar o principal de uma entidade, use o argumento parent
para datastore.NewKey
. O valor deste argumento deve ser a chave da entidade principal. O exemplo seguinte cria uma entidade do tipo Address
e designa uma entidade Employee
como a respetiva entidade principal:
Transações e grupos de entidades
Todas as tentativas de criar, atualizar ou eliminar uma entidade ocorrem no contexto de uma transação. Uma única transação pode incluir qualquer número dessas operações. Para manter a consistência dos dados, a transação garante que todas as operações que contém são aplicadas ao Datastore como uma unidade ou, se alguma das operações falhar, que nenhuma delas é aplicada. Além disso, todas as leituras fortemente consistentes (consultas de antecessores ou obtenções) realizadas na mesma transação observam um instantâneo consistente dos dados.
Conforme mencionado acima, um grupo de entidades é um conjunto de entidades ligadas através da ascendência a um elemento raiz comum. A organização dos dados em grupos de entidades pode limitar as transações que podem ser realizadas:
- Todos os dados acedidos por uma transação têm de estar contidos num máximo de 25 grupos de entidades.
- Se quiser usar consultas numa transação, os seus dados têm de estar organizados em grupos de entidades de forma que possa especificar filtros de antecessores que correspondam aos dados certos.
- Existe um limite de débito de gravação de cerca de uma transação por segundo num único grupo de entidades. Esta limitação existe porque o Datastore executa a replicação síncrona sem mestre de cada grupo de entidades numa vasta área geográfica para oferecer elevada fiabilidade e tolerância a falhas.
Em muitas aplicações, é aceitável usar a consistência eventual (ou seja, uma consulta não ancestral que abranja vários grupos de entidades, que pode, por vezes, devolver dados ligeiramente desatualizados) quando obtém uma vista geral de dados não relacionados e, em seguida, usar a consistência forte (uma consulta ancestral ou um get
de uma única entidade) quando visualiza ou edita um único conjunto de dados altamente relacionados. Em tais aplicações, é normalmente uma boa abordagem usar um grupo de entidades separado para cada conjunto de dados altamente relacionados.
Para mais informações, consulte o artigo Estruturar para uma forte consistência.
Propriedades e tipos de valores
Os valores de dados associados a uma entidade consistem numa ou mais propriedades. Cada propriedade tem um nome e um ou mais valores. Uma propriedade pode ter valores de mais do que um tipo, e duas entidades podem ter valores de tipos diferentes para a mesma propriedade. As propriedades podem ser indexadas ou não indexadas (as consultas que ordenam ou filtram uma propriedade P ignoram as entidades em que P não está indexada). Uma entidade pode ter, no máximo, 20 000 propriedades indexadas.
São suportados os seguintes tipos de valores:
Tipo de valor | Tipos de deslocações | Ordenação | Notas |
---|---|---|---|
Número inteiro | int int8 int16 int32 int64 |
Numérico | Número inteiro de 64 bits, com sinal |
Número de vírgula flutuante | float32 float64 |
Numérico | Precisão dupla de 64 bits, IEEE 754 |
Booleano | bool |
false <true |
|
String (curta) | string |
Unicode |
Até 1500 bytes. Os valores com mais de 1500 bytes resultam num erro no tempo de execução. |
String (longa) | string (com noindex ) |
Nenhum | Até 1 megabyte Não indexado |
Intervalo de bytes (curto) | datastore.ByteString |
Ordem dos bytes | Até 1500 bytes. Os valores com mais de 1500 bytes resultam num erro no tempo de execução. |
Segmento de bytes (longo) | []byte |
Nenhum | Até 1 megabyte Não indexado |
Data e hora | time.Time |
Cronológico | |
Ponto geográfico | appengine.GeoPoint |
Por latitude, depois longitude |
|
Chave do armazenamento de dados | *datastore.Key |
Por elementos de caminho (tipo, identificador, tipo, identificador...) |
|
Chave do Blobstore | appengine.BlobKey |
Ordem dos bytes |
Também pode usar um struct
ou um slice
para agregar propriedades. Consulte a referência do Datastore para ver mais detalhes.
Quando uma consulta envolve uma propriedade com valores de tipos mistos, o Datastore usa uma ordenação determinística com base nas representações internas:
- Valores nulos
- Números de ponto fixo
- Números inteiros
- Datas e horas
- Valores booleanos
- Sequências de bytes
- Fatias de bytes (curto)
- String Unicode
- Chaves do Blobstore
- Números de vírgula flutuante
- Pontos geográficos
- Chaves do Datastore
Uma vez que as fatias de bytes longas e as strings longas não são indexadas, não têm uma ordem definida.
Trabalhar com entidades
As aplicações podem usar a API Datastore para criar, obter, atualizar e eliminar entidades. Se a aplicação souber a chave completa de uma entidade (ou puder derivá-la da respetiva chave principal, tipo e identificador), pode usar a chave para operar diretamente na entidade. Uma aplicação também pode obter a chave de uma entidade como resultado de uma consulta do Datastore. Consulte a página Consultas do Datastore para mais informações.
Criar uma entidade
Em Go, cria uma nova entidade construindo uma instância de uma struct Go, preenchendo os respetivos campos e chamando datastore.Put
para a guardar no Datastore. Apenas os campos exportados (que começam com uma letra maiúscula) são guardados no Datastore. Pode especificar o nome da chave da entidade transmitindo um argumento stringID
não vazio a datastore.NewKey
:
Se fornecer um nome de chave vazio ou usar datastore.NewIncompleteKey
, o Datastore gera automaticamente um ID numérico para a chave da entidade:
Obter uma entidade
Para obter uma entidade identificada por uma determinada chave, transmita o *datastore.Key
como um argumento para a função datastore.Get
. Pode gerar o *datastore.Key
através da função datastore.NewKey
.
datastore.Get
preenche uma instância da estrutura Go adequada.
Atualizar uma entidade
Para atualizar uma entidade existente, modifique os atributos da struct e, em seguida, chame datastore.Put
. Os dados substituem a entidade existente. O objeto completo é enviado para o Datastore com cada chamada para datastore.Put
.
Eliminar uma entidade
Dada a chave de uma entidade, pode eliminar a entidade com a função datastore.Delete
:
Operações em lote
datastore.Put
,
datastore.Get
e
datastore.Delete
têm variantes em massa denominadas
datastore.PutMulti
,
datastore.GetMulti
e
datastore.DeleteMulti
.
Permitem agir em várias entidades numa única chamada do Datastore:
As operações em lote não alteram os seus custos. É-lhe cobrado o valor de cada chave numa operação em lote, quer a chave exista ou não. A dimensão das entidades envolvidas numa operação não afeta o custo.