Tipos de dados

O Cloud Spanner aceita tipos de dados simples, como inteiros, e tipos mais complexos, como ARRAY e STRUCT. Esta página fornece uma visão geral de cada tipo de dados, incluindo os valores permitidos.

O tamanho máximo de um valor de coluna é 10 MiB, que se aplica aos tipos escalares e de matrizes.

Tipos permitidos

Nome do tipo Tipo de coluna válido? Tipo de coluna chave válida? Tipo de SQL válido? Tamanho de armazenamento1
ARRAY sim não sim A soma do tamanho de seus elementos
BOOL sim sim sim 1 byte
BYTES sim sim sim O número de bytes
DATE sim sim sim 4 bytes
FLOAT64 sim sim sim 8 bytes
INT64 sim sim sim 8 bytes
STRING sim sim sim O número de bytes em sua codificação UTF-8
STRUCT não não sim Não aplicável
TIMESTAMP sim sim sim 12 bytes

1Cada célula também tem 8 bytes de sobrecarga de armazenamento, além dos valores listados.

Propriedades dos tipos de dados

Ao armazenar e consultar dados, vale a pena ter em mente as seguintes propriedades de tipos de dados:

Propriedade Descrição É aplicável a
Anulável NULL é um valor válido. Todos os tipos de dados.

Ordenável Pode ser usada em uma cláusula ORDER BY. Todos os tipos de dados, exceto:

  • ARRAY
  • STRUCT
Geralmente, pode aparecer em uma expressão após
GROUP BY, DISTINCT ou PARTITION BY.
No entanto, as expressões PARTITION BY não podem incluir
os tipos de ponto flutuante FLOAT e DOUBLE.


Todos os tipos de dados, exceto:
  • ARRAY
  • STRUCT
Valores do mesmo tipo podem ser comparados entre si. Todos os tipos de dados, com as seguintes exceções:

As comparações de ARRAY não são aceitas.



Comparações de igualdade de STRUCTs são aceitas campo por campo, na ordem dos campos. Nomes de campos são ignorados. As comparações "menor que" e "maior que" não são aceitas.





Todos os tipos que aceitam comparações podem ser usados em uma condição JOIN. Consulte Tipos JOIN para uma explicação das condições de junção.

Tipos numéricos

Entre tipos numéricos estão tipos inteiros e tipos de ponto flutuante.

Tipo inteiro

Inteiros são valores numéricos que não têm componentes fracionários.

Nome Tamanho do armazenamento Intervalo
INT64 8 bytes -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807

Tipo ponto flutuante

Valores de ponto flutuante são valores numéricos aproximados com componentes fracionários.

Nome Tamanho do armazenamento Descrição
FLOAT64 8 bytes Valores decimais de precisão dupla (aproximada).

Semântica de ponto flutuante

Ao trabalhar com números de ponto flutuante, você deve considerar alguns valores não numéricos especiais: NaN e +/-inf.

Formate os valores especiais de ponto flutuante como Infinity, -Infinity e NaN ao usar as APIs REST e RPC do Cloud Spanner, conforme documentado em TypeCode (REST) e TypeCode (RPC). Os literais +inf, -inf e nan não são aceitos em APIs REST e RPC do Cloud Spanner.

Operadores aritméticos proporcionam comportamento IEEE-754 padrão a todos os valores de entrada finitos que produzem saída finita e a todas as operações para as quais pelo menos uma entrada é não finita.

Chamadas de função e operadores retornam um erro de estouro quando a entrada é finita, mas a saída pode ser não finita. Se a entrada contém valores não finitos, a saída pode ser não finita. Em geral, as funções não apresentam NaNs ou +/-inf. Porém, funções específicas como IEEE_DIVIDE podem retornar valores não finitos em saída finita. Todos esses casos são representados explicitamente por funções matemáticas.

Exemplos de funções matemáticas
Formate os valores especiais de ponto flutuante como Infinity, -Infinity e NaN ao usar as APIs REST e RPC do Cloud Spanner, conforme documentado em TypeCode (REST) e TypeCode (RPC). Os literais +inf, -inf e nan não são aceitos em APIs REST e RPC do Cloud Spanner.
Termo esquerdo Operador Termo direito Retorna
Qualquer valor + NaN NaN
1.0 + +inf +inf
1.0 + -inf -inf
-inf + +inf NaN
Valor máximo de FLOAT64 + Valor máximo de FLOAT64 Erro de estouro
Valor mínimo de FLOAT64 / 2.0 0.0
1.0 / 0.0 Erro "divisão por zero"

Operadores de comparação proporcionam comportamento IEEE-754 padrão à entrada de ponto flutuante.

Exemplos de operadores de comparação
Termo esquerdo Operador Termo direito Retorna
NaN = Qualquer valor FALSE
NaN < Qualquer valor FALSE
Qualquer valor < NaN FALSE
-0.0 = 0.0 TRUE
-0.0 < 0.0 FALSE

Valores de ponto flutuante são classificados nesta ordem, do menor para o maior:

  1. NULL
  2. NaN — todos os valores NaN são considerados iguais no momento da classificação.
  3. -inf
  4. Números negativos
  5. 0 ou -0 — todos os valores zero são considerados iguais no momento da classificação.
  6. Números positivos
  7. +inf

Valores de ponto flutuante especiais são agrupados desta forma, incluindo o agrupamento feito por uma cláusula GROUP BY e o agrupamento feito pela palavra-chave DISTINCT:

  • NULL
  • NaN — todos os valores NaN são considerados iguais no momento do agrupamento.
  • -inf
  • 0 ou -0 — todos os valores zero são considerados iguais no momento do agrupamento.
  • +inf

Tipo booleano

Nome Descrição
BOOL Valores booleanos são representados pelas palavras-chave TRUE e FALSE (sem distinção de maiúsculas e minúsculas).

Tipo string

Nome Descrição
STRING Dados em caracteres de comprimento variável (Unicode).

Os valores STRING de entrada precisam ter codificação UTF-8, e os valores STRING de saída terão codificação UTF-8. Codificações alternativas como CESU-8 e UTF-8 modificado não são tratadas como UTF-8 válida.

Todas as funções e operadores que atuam sobre valores STRING atuam sobre caracteres Unicode em vez de bytes. Por exemplo, funções como SUBSTR e LENGTH aplicadas à entrada STRING contam caracteres Unicode, não bytes. As comparações são definidas em caracteres Unicode. As comparações de "menor que" e ORDER BY comparam caractere por caractere, e os pontos de código Unicode inferiores são considerados caracteres inferiores.

A maioria das funções em STRING também são definidas em BYTES. A versão BYTES atua sobre bytes brutos em vez de caracteres Unicode. STRING e BYTES são tipos distintos que não podem ser usados alternadamente. Não ocorre cast implícito em nenhuma direção. O cast explícito entre STRING e BYTES faz codificação e decodificação UTF-8. O cast de BYTES para STRING retorna um erro quando os bytes não estão em UTF-8 válido.

Tipo bytes

Nome Descrição
BYTES Dados binários de comprimento variável.

STRING e BYTES são tipos distintos que não podem ser usados alternadamente. A maioria das funções em STRING também são definidas em BYTES. A versão BYTES atua sobre bytes brutos em vez de caracteres Unicode. Casts entre STRING e BYTES impõem que os bytes sejam codificados usando UTF-8.

Tipo date

Nome Descrição Intervalo
DATE Representa uma data do calendário lógico. 0001-01-01 a 9999-12-31.

O tipo DATE representa uma data de calendário lógico, independente do fuso horário. Um valor DATE não representa um período de tempo específico de 24 horas. Em vez disso, representa um período diferente de 24 horas quando interpretado em fusos horários diferentes, podendo representar um dia mais curto ou mais longo durante as transições de horário de verão. Para representar um ponto absoluto no tempo, use timestamp.

Formato canônico

'YYYY-[M]M-[D]D'
  • YYYY: ano de quatro dígitos
  • [M]M: mês de um ou dois dígitos
  • [D]D: dia de um ou dois dígitos

Tipo timestamp

Nome Descrição Intervalo
TIMESTAMP Representa um ponto absoluto no tempo, com precisão de microssegundos. 0001-01-01 00:00:00 to 9999-12-31 23:59:59.999999999 UTC.

Um carimbo de data/hora representa um ponto absoluto no tempo, independentemente de qualquer fuso horário ou convenção, como o horário de verão.

TIMESTAMP fornece precisão de nanossegundos.

Formato canônico

Para APIs Rest e RPC

Siga as regras para codificação e decodificação de valores JSON, conforme descrito em TypeCode (RPC) e TypeCode (REST). Particularmente, o valor do carimbo de data/hora precisa terminar com um "Z" literal maiúsculo para especificar o tempo Zulu (UTC-0).

Por exemplo:

2014-09-27T12:30:00.45Z

Os valores de carimbo de data/hora precisam ser expressos no tempo Zulu e não podem incluir uma diferença UTC. O carimbo de data/hora a seguir, por exemplo, não é aceito:

-- NOT SUPPORTED! TIMESTAMPS CANNOT INCLUDE A UTC OFFSET WHEN USED WITH THE REST AND RPC APIS
2014-09-27 12:30:00.45-8:00

Para bibliotecas de clientes

Use o formato de carimbo de data/hora específico do idioma.

Para consultas SQL

YYYY-[M]M-[D]D[( |T)[H]H:[M]M:[S]S[.DDDDDDDDD]][time zone]
  • YYYY: ano de quatro dígitos
  • [M]M: mês de um ou dois dígitos
  • [D]D: dia de um ou dois dígitos
  • ( |T) : um espaço ou um separador de T
  • [H]H: hora de um ou dois dígitos (valores válidos de 00 a 23)
  • [M]M: minutos de um ou dois dígitos (valores válidos de 00 a 59)
  • [S]S: segundos de um ou dois dígitos (valores válidos de 00 a 59)
  • [.DDDDDDDDD]: até nove dígitos fracionários (isto é, até a precisão de nanossegundos)
  • [time zone]: string que representa o fuso horário. Consulte a seção fusos horários para ver detalhes.

Os fusos horários são usados ao analisar ou formatar carimbos de data/hora para exibição. O próprio valor de carimbo de data/hora não armazena um fuso horário específico. Um carimbo de data/hora formatado como string pode incluir um fuso horário. Quando um fuso horário não é explicitamente especificado, é usado o fuso horário padrão, America/Los_Angeles.

Fusos horários

Fusos horários são representados por strings em um destes dois formatos canônicos:

  • Diferença do Tempo Universal Coordenado (UTC) ou da letra Z para UTC
  • Nome do fuso horário proveniente do banco de dados tz

Diferença do Tempo Universal Coordenado (UTC, na sigla em inglês)

Formato de diferença
(+|-)H[H][:M[M]]
Z
Exemplos
-08:00
-8:15
+3:00
+07:30
-7
Z

Quando se usa esse formato, nenhum espaço é permitido entre o fuso horário e o resto do carimbo de data/hora.

2014-09-27 12:30:00.45-8:00
2014-09-27T12:30:00.45Z

Nome do fuso horário

Os nomes de fuso horário provêm do banco de dados tz. Para uma referência menos abrangente e mais simples, consulte a Lista de fusos horários do banco de dados tz na Wikipédia.

Formato
continent/[region/]city
Exemplos
America/Los_Angeles
America/Argentina/Buenos_Aires

Quando se usa um nome de fuso horário, é necessário um espaço entre o nome e o resto do carimbo de data/hora.

2014-09-27 12:30:00.45 America/Los_Angeles

Observe que nem todos os nomes de fuso horário são intercambiáveis, mesmo se informarem a mesma hora durante uma determinada parte do ano. Por exemplo, America/Los_Angeles informa a mesma hora que UTC-7:00 durante o horário de verão, mas informa a mesma hora que UTC-8:00 fora do horário de verão.

Se não houver especificação de fuso horário, será usado o valor padrão.

Segundos bissextos

Um timestamp é simplesmente uma diferença de 1970-01-01 00:00:00 UTC, supondo-se que haja exatamente 60 segundos por minuto. Os segundos bissextos não são representados como parte de um timestamp armazenado.

Se a sua entrada contém valores que usam ":60" no campo de segundos para representar um segundo bissexto, esse segundo bissexto não é preservado na conversão para um valor de timestamp. Em vez disso, o valor é interpretado como um timestamp com ":00" no campo de segundos do minuto seguinte.

Os segundos bissextos não afetam os cálculos de timestamp. Todos os cálculos de timestamp são feitos com carimbos de data/hora no estilo Unix, que não refletem segundos bissextos. Só é possível perceber os segundos bissextos por meio de funções que medem o tempo do mundo real. Nessas funções, é possível pular ou repetir um segundo de timestamp quando há um segundo bissexto.

Tipo array

Nome Descrição
ARRAY Lista ordenada de zero ou mais elementos de qualquer tipo não ARRAY.

Um ARRAY é uma lista ordenada de zero ou mais elementos de valores não ARRAY. Não pode haver ARRAYs de ARRAYs. Consultas que produzam um ARRAY de ARRAYs retornam erro. É preciso inserir um STRUCT entre os ARRAYs usando a construção SELECT AS STRUCT.

Um ARRAY vazio e um ARRAY NULL são dois valores distintos. ARRAYs podem conter elementos NULL.

Declaração de um tipo ARRAY

Os tipos ARRAY são declarados com o uso de parênteses angulares (< e >). O tipo dos elementos de um ARRAY pode ser arbitrariamente complexo, com exceção de que um ARRAY não pode conter diretamente outro ARRAY.

Formato

ARRAY<T>

Exemplos

Declaração do tipo Significado
ARRAY<INT64> ARRAY simples de inteiros de 64 bits.
ARRAY<STRUCT<INT64, INT64>> Um ARRAY de STRUCTs contendo, cada um, dois inteiros de 64 bits.
Observação: os valores de ARRAY de STRUCTs podem ser construídos por expressões SQL, mas não são aceitos como tipos de coluna.
ARRAY<ARRAY<INT64>>
(incompatível)
Uma declaração de tipo inválido incluída aqui apenas para o caso de você querer saber como criar um ARRAY de vários níveis. ARRAYs não podem conter ARRAYs diretamente. Veja o próximo exemplo:
ARRAY<STRUCT<ARRAY<INT64>>> Um ARRAY de ARRAYS de inteiros de 64 bits. Observe que há um STRUCT entre os dois ARRAYs porque os ARRAYs não podem conter outros ARRAYs diretamente.
Observação: os valores de ARRAY de STRUCTs podem ser construídos por expressões SQL, mas não são aceitos como tipos de coluna.

Tipo struct

Veja detalhes sobre o uso de STRUCTs em instruções SELECT e subconsultas na página "Sintaxe de consulta".

Nome Descrição
STRUCT Contêiner de campos ordenados, cada um com um tipo (obrigatório) e um nome de campo (opcional).

Declaração de um tipo STRUCT

Tipos STRUCT são declarados com o uso de parênteses angulares (< e >). O tipo dos elementos de um STRUCT pode ser arbitrariamente complexo.

Formato

STRUCT<T>
Observação: valores STRUCT podem ser construídos por expressões SQL, mas não são aceitos como tipos de colunas.

Exemplos

Declaração do tipo Significado
STRUCT<INT64> STRUCT simples com um único campo de inteiro de 64 bits sem nome.
STRUCT<x STRUCT<y INT64, z INT64>> Um STRUCT com um STRUCT aninhado com o nome x em seu interior. O STRUCT x tem dois campos, y e z, ambos inteiros de 64 bits.
STRUCT<inner_array ARRAY<INT64>> Um STRUCT contendo um ARRAY com o nome inner_array que contém elementos inteiros de 64 bits.

Construção de um STRUCT

Sintaxe de tupla

Formato
(expr1, expr2 [, ... ])

O tipo de saída é um STRUCT anônimo com campos anônimos, cujos tipos correspondem aos tipos das expressões de entrada. É preciso especificar pelo menos duas expressões. Caso contrário, não se distingue essa sintaxe de uma expressão envolvida por parênteses.

Exemplos
Sintaxe Tipo de saída Notas
(x, x+y) STRUCT<?,?> Se forem usados nomes de coluna (strings sem aspas), o tipo de dados do campo STRUCT será derivado do tipo de dados de coluna. Como x e y são colunas, os tipos de dados dos campos STRUCT são derivados dos tipos de coluna e do tipo de saída do operador de adição.

Essa sintaxe também pode ser usada com a comparação de STRUCT nas expressões de comparação usando-se chaves de várias partes, por exemplo, em uma cláusula WHERE:

WHERE (Key1,Key2) IN ( (12,34), (56,78) )

Sintaxe de struct sem especificação de tipo

Formato
STRUCT( expr1 [AS field_name] [, ... ])

Não é permitido duplicar nomes de campo. Os campos sem nome são considerados anônimos e não é possível referenciá-los pelo nome. Os valores de STRUCT podem ser NULL ou ter valores de campo NULL.

Exemplos
Sintaxe Tipo de saída
STRUCT(1,2,3) STRUCT<int64,int64,int64>
STRUCT() STRUCT<>
STRUCT('abc') STRUCT<string>
STRUCT(1, t.str_col) STRUCT<int64, str_col string>
STRUCT(1 AS a, 'abc' AS b) STRUCT<a int64, b string>
STRUCT(str_col AS abc) STRUCT<abc string>

Sintaxe de struct com especificação de tipo

Formato
STRUCT<[field_name] field_type, ...>( expr1 [, ... ])

A sintaxe tipada permite construir STRUCTs com um tipo de dados STRUCT explícito. O tipo de saída é exatamente o field_type fornecido. A expressão de entrada será forçada para field_type se os dois tipos não forem iguais, e será produzido um erro se os tipos não forem compatíveis entre si. AS alias não é permitido nas expressões de entrada. O número de expressões precisa corresponder ao número de campos do tipo, e os tipos de expressão precisam ser coercíveis ou literais-coercíveis para os tipos de campo.

Exemplos
Sintaxe Tipo de saída
STRUCT<int64>(5) STRUCT<int64>
STRUCT<date>("2011-05-05") STRUCT<date>
STRUCT<x int64, y string>(1, t.str_col) STRUCT<x int64, y string>
STRUCT<int64>(int_col) STRUCT<int64>
STRUCT<x int64>(5 AS x) Erro - sintaxe tipada não permite AS

Comparações limitadas de STRUCT

STRUCTs podem ser diretamente comparados usando-se operadores de igualdade:

  • Igual (=)
  • Diferente de (!= ou <>)
  • [NOT] IN

Observe, porém, que essas comparações de igualdade diretas comparam os campos do STRUCT em pares na ordem de ordinais, ignorando nomes de campo. Se você preferir comparar campos com nomes idênticos de um STRUCT, poderá comparar os campos individuais diretamente.

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação do Cloud Spanner