Capítulo 8. Tipos de dados

Sumário
8.1. Tipos numéricos
8.1.1. Tipos inteiros
8.1.2. Números com precisão arbitrária
8.1.3. Tipos de ponto flutuante
8.1.4. Tipos seriais
8.2. Tipos monetários
8.3. Tipos para cadeias de caracteres
8.4. Tipos de dado binários
8.5. Tipos para data e hora
8.5.1. Entrada de data e hora
8.5.2. Saídas de data e hora
8.5.3. Zonas horárias
8.5.4. Internamente
8.6. Tipo booleano
8.7. Tipos geométricos
8.7.1. Pontos
8.7.2. Segmentos de linha
8.7.3. Caixas
8.7.4. Caminhos
8.7.5. Polígonos
8.7.6. Círculos
8.8. Tipos para endereço de rede
8.8.1. inet
8.8.2. cidr
8.8.3. inet versus cidr
8.8.4. macaddr
8.9. Tipos para cadeias de bits
8.10. Matrizes
8.10.1. Declaração do tipo matriz
8.10.2. Entrada de valor matriz
8.10.3. Acesso às matrizes
8.10.4. Modificação de matrizes
8.10.5. Procura em matrizes
8.10.6. Sintaxe de entrada e de saída das matrizes
8.11. Tipos compostos
8.11.1. Declaração de tipos compostos
8.11.2. Entrada de valor composto
8.11.3. Acesso aos tipos compostos
8.11.4. Modificação de tipos compostos
8.11.5. Sintaxe de entrada e saída dos tipos compostos
8.12. Tipos identificadores de objeto
8.13. Pseudotipos

O PostgreSQL disponibiliza para os usuários um amplo conjunto de tipos de dado nativos. Os usuários podem adicionar novos tipos ao PostgreSQL utilizando o comando CREATE TYPE. [1] [2] [3]

A Tabela 8-1 mostra todos os tipos de dado nativos de propósito geral. A maioria dos nomes alternativos listados na coluna "Aliases" é o nome utilizado internamente pelo PostgreSQL por motivos históricos. Além desses, existem alguns tipos usados internamente ou em obsolescência (deprecated [4] ) que não são mostrados aqui.

Tabela 8-1. Tipos de dado

Nome Aliases Descrição
bigint int8 inteiro de oito bytes com sinal [a]
bigserial serial8 inteiro de oito bytes com auto-incremento
bit [ (n) ]   cadeia de bits de comprimento fixo
bit varying [ (n) ] varbit cadeia de bits de comprimento variável [b]
boolean bool booleano lógico (verdade/falso)
box   caixa retangular no plano
bytea   dados binários ("matriz de bytes")
character varying [ (n) ] varchar [ (n) ] cadeia de caracteres de comprimento variável [c]
character [ (n) ] char [ (n) ] cadeia de caracteres de comprimento fixo
cidr   endereço de rede IPv4 ou IPv6
circle   círculo no plano
date   data de calendário (ano, mês,dia)
double precision float8 número de ponto flutuante de precisão dupla [d]
inet   endereço de hospedeiro IPv4 ou IPv6
integer int, int4 inteiro de quatro bytes com sinal
interval [ (p) ]   espaço de tempo
line   linha infinita no plano
lseg   segmento de linha no plano
macaddr   endereço MAC
money   quantia monetária
numeric [ (p, s) ] decimal [ (p, s) ] numérico exato com precisão selecionável
path   caminho geométrico no plano
point   ponto geométrico no plano
polygon   caminho geométrico fechado no plano
real float4 número de ponto flutuante de precisão simples
smallint int2 inteiro de dois bytes com sinal
serial serial4 inteiro de quatro bytes com auto-incremento
text   cadeia de caracteres de comprimento variável
time [ (p) ] [ without time zone ]   hora do dia
time [ (p) ] with time zone timetz hora do dia, incluindo a zona horária
timestamp [ (p) ] [ without time zone ]   data e hora
timestamp [ (p) ] with time zone timestamptz data e hora, incluindo a zona horária
Notas:
a. Os tipos de dado NUMERIC, DECIMAL, SMALLINT, INTEGER e BIGINT são referenciados coletivamente como tipos numéricos exatos. (ISO-ANSI Working Draft) Foundation (SQL/Foundation), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-2:2003 (E) (N. do T.)
b. comprimento variável — uma característica das cadeias de caracteres e das cadeias binárias que permite as cadeias conterem qualquer número de caracteres ou de octetos, respectivamente, entre zero e um número máximo, conhecido como comprimento máximo em caracteres ou octetos, respectivamente, da cadeia. (ISO-ANSI Working Draft) Foundation (SQL/Foundation), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-2:2003 (E) (N. do T.)
c. Os tipos de dado CHARACTER, CHARACTER VARYING e CHARACTER LARGE OBJECT são referenciados coletivamente como tipos cadeia de caracteres. (ISO-ANSI Working Draft) Foundation (SQL/Foundation), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-2:2003 (E) (N. do T.)
d. Os tipos de dado FLOAT, REAL e DOUBLE PRECISION são referenciados coletivamente como tipos numéricos aproximados. (ISO-ANSI Working Draft) Foundation (SQL/Foundation), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-2:2003 (E) (N. do T.)

Compatibilidade: Os seguintes tipos (ou a citação destes) são especificados pelo padrão SQL: bit, bit varying, boolean, char, character varying, character, varchar, date, double precision, integer, interval, numeric, decimal, real, smallint, time (com ou sem zona horária), timestamp (com ou sem zona horária).

Cada tipo de dado possui uma representação externa determinada pelas suas funções de entrada e de saída. Muitos tipos nativos possuem formato externo óbvio. Entretanto, muitos tipos existem apenas no PostgreSQL, como os caminhos geométricos, ou possuem várias possibilidades para o formato, como os tipos de data e hora. Algumas das funções de entrada e saída não são inversíveis, ou seja, o resultado da função de saída pode perder precisão quando comparado com a entrada original.

8.1. Tipos numéricos

Os tipos numéricos consistem em inteiros de dois, quatro e oito bytes, números de ponto flutuante de quatro e oito bytes, e decimais de precisão selecionável. A Tabela 8-2 lista os tipos disponíveis.

Tabela 8-2. Tipos numéricos

Nome Tamanho de armazenamento Descrição Faixa de valores
smallint 2 bytes inteiro com faixa pequena -32768 a +32767
integer 4 bytes escolha usual para inteiro -2147483648 a +2147483647
bigint 8 bytes inteiro com faixa larga -9223372036854775808 a 9223372036854775807
decimal variável precisão especificada pelo usuário, exato sem limite
numeric variável precisão especificada pelo usuário, exato sem limite
real 4 bytes precisão variável, inexato precisão de 6 dígitos decimais
double precision 8 bytes precisão variável, inexato precisão de 15 dígitos decimais
serial 4 bytes inteiro com auto-incremento 1 a 2147483647
bigserial 8 bytes inteiro grande com auto-incremento 1 a 9223372036854775807

A sintaxe das constantes para os tipos numéricos é descrita na Seção 4.1.2. Os tipos numéricos possuem um conjunto completo de operadores aritméticos e funções correspondentes. Consulte o Capítulo 9 para obter informações adicionais. As próximas seções descrevem os tipos em detalhe.

8.1.1. Tipos inteiros

Os tipos smallint, integer e bigint armazenam números inteiros, ou seja, números sem a parte fracionária, com faixas diferentes. A tentativa de armazenar um valor fora da faixa permitida resulta em erro.

O tipo integer é a escolha usual, porque oferece o melhor equilíbrio entre faixa de valores, tamanho de armazenamento e desempenho. Geralmente o tipo smallint só é utilizado quando o espaço em disco está muito escasso. O tipo bigint somente deve ser usado quando a faixa de valores de integer não for suficiente, porque este último é bem mais rápido.

O tipo bigint pode não funcionar de modo correto em todas as plataformas, porque depende de suporte no compilador para inteiros de oito bytes. Nas máquinas sem este suporte, o bigint age do mesmo modo que o integer (mas ainda ocupa oito bytes de armazenamento). Entretanto, não é de nosso conhecimento nenhuma plataforma razoável onde este caso se aplique.

O padrão SQL somente especifica os tipos inteiros integer (ou int) e smallint. O tipo bigint, e os nomes de tipo int2, int4 e int8 são extensões, também compartilhadas por vários outros sistemas de banco de dados SQL.

8.1.2. Números com precisão arbitrária

O tipo numeric pode armazenar números com precisão de até 1.000 dígitos e realizar cálculos exatos. É recomendado, especialmente, para armazenar quantias monetárias e outras quantidades onde se requeira exatidão. Entretanto, a aritmética em valores do tipo numeric é muito lenta se comparada com os tipos inteiros, ou com os tipos de ponto flutuante descritos na próxima seção.

São utilizados os seguintes termos: A escala do tipo numeric é o número de dígitos decimais da parte fracionária, à direita do ponto decimal. A precisão do tipo numeric é o número total de dígitos significativos de todo o número, ou seja, o número de dígitos nos dois lados do ponto decimal. Portanto, o número 23.5141 [5] possui precisão igual a 6 e escala igual a 4. Os inteiros podem ser considerados como tendo escala igual a zero.

Tanto a precisão máxima quanto a escala de uma coluna do tipo numeric podem ser configuradas. Para declarar uma coluna do tipo numeric é utilizada a sintaxe:

NUMERIC(precisão, escala)

A precisão deve ser um número positivo, enquanto a escala pode ser zero ou positiva. Como forma alternativa,

NUMERIC(precisão)

define a escala como sendo igual a 0. Especificando-se

NUMERIC

sem qualquer precisão ou escala é criada uma coluna onde podem ser armazenados valores numéricos com qualquer precisão ou escala, até a precisão limite da implementação. Uma coluna deste tipo não converte os valores de entrada para nenhuma escala em particular, enquanto as colunas do tipo numeric com escala declarada convertem os valores da entrada para esta escala (O padrão SQL requer a escala padrão igual a 0, ou seja, uma conversão para a precisão inteira. Isto foi considerado sem utilidade. Havendo preocupação com a portabilidade, a precisão e a escala devem ser sempre especificadas explicitamente).

Se a escala do valor a ser armazenado for maior que a escala declarada para a coluna, o sistema arredonda o valor para o número de dígitos fracionários especificado. Depois, se o número de dígitos à esquerda do ponto decimal exceder a precisão declarada menos a escala declarada, é gerado um erro.

Exemplo 8-1. Arredondamento em tipo numeric

Abaixo estão mostrados exemplos de inserção de dados em um campo do tipo numeric. No terceiro exemplo o arredondamento faz com que a precisão do campo seja excedida. [6]

A execução deste exemplo no SQL Server 2000 e no Oracle 10g produziu o mesmo resultado, mas o DB2 8.1 em vez de arredondar trunca as casas decimais e, por isso, a precisão não é excedida.

BEGIN;
CREATE TEMPORARY TABLE t ( c NUMERIC(6,3)) ON COMMIT DROP;
INSERT INTO t VALUES (998.9991);
INSERT INTO t VALUES (998.9999);
SELECT * FROM t;

    c
---------
 998.999
 999.000
(2 linhas)

INSERT INTO t VALUES (999.9999);

ERRO:  estouro de campo numérico
DETALHE:  O valor absoluto é maior ou igual a 10^3 para campo com precisão 6, escala 3.

COMMIT;
ROLLBACK

Os valores numéricos são armazenados fisicamente sem zeros adicionais no início ou no final. Portanto, a precisão e a escala declaradas para uma coluna são as alocações máximas, e não fixas (Sob este aspecto o tipo numeric é mais semelhante ao tipo varchar(n) do que ao tipo char(n)).

Além dos valores numéricos ordinários o tipo numeric aceita o valor especial NaN, que significa "não-é-um-número" (not-a-number). Toda operação envolvendo NaN produz outro NaN. Para escrever este valor como uma constante em um comando SQL deve-se colocá-lo entre apóstrofos como, por exemplo, UPDATE tabela SET x = 'NaN'. Na entrada, a cadeia de caracteres NaN é reconhecida sem que haja distinção entre letras maiúsculas e minúsculas.

Os tipos decimal e numeric são equivalentes. Os dois tipos fazem parte do padrão SQL.

8.1.3. Tipos de ponto flutuante

Os tipos de dado real e double precision são tipos numéricos não exatos de precisão variável. Na prática, estes tipos são geralmente implementações do "Padrão IEEE 754 para Aritmética Binária de Ponto Flutuante" (de precisão simples e dupla, respectivamente), conforme suportado pelo processador, sistema operacional e compilador utilizados.

Não exato significa que alguns valores não podem ser convertidos exatamente para o formato interno, sendo armazenados como aproximações. Portanto, ao se armazenar e posteriormente imprimir um valor podem ocorrer pequenas discrepâncias. A gerência destes erros, e como se propagam através dos cálculos, é assunto de um ramo da matemática e da ciência da computação que não será exposto aqui, exceto os seguintes pontos:

  • Se for necessário armazenamento e cálculos exatos (como em quantias monetárias), em vez de tipos de ponto flutuante deve ser utilizado o tipo numeric.

  • Se for desejado efetuar cálculos complicados usando tipos de ponto flutuante para algo importante, especialmente dependendo de certos comportamentos em situações limites (infinito ou muito próximo de zero), a implementação deve ser avaliada cuidadosamente.

  • A comparação de igualdade de dois valores de ponto flutuante pode funcionar conforme o esperado, ou não.

Na maioria das plataformas o tipo real possui uma faixa de pelo menos 1E-37 a 1E+37, com precisão de pelo menos 6 dígitos decimais. O tipo double precision normalmente possui uma faixa em torno de 1E-307 a 1E+308 com precisão de pelo menos 15 dígitos. Os valores muito pequenos ou muito grandes causam erro. O arredondamento pode acontecer se a precisão do número entrado for muito grande. Os números muito próximos de zero, que não podem ser representados de forma distinta de zero, causam erro de underflow.

Além dos valores numéricos ordinários, os tipos de ponto flutuante possuem diversos valores especiais:

Infinity
-Infinity
NaN

Estes valores representam os valores especiais do padrão IEEE 754 "infinito", "infinito negativo" e "não-é-um-número", respectivamente (Nas máquinas cuja aritmética de ponto flutuante não segue o padrão IEEE 754, estes valores provavelmente não vão funcionar da forma esperada). Ao se escrever estes valores como constantes em um comando SQL deve-se colocá-los entre apóstrofos como, por exemplo, UPDATE tabela SET x = 'Infinity'. Na entrada, estas cadeias de caracteres são reconhecidas sem que haja distinção entre letras maiúsculas e minúsculas

O PostgreSQL também suporta a notação do padrão SQL float e float(p) para especificar tipos numéricos inexatos. Neste caso, p especifica a precisão mínima aceitável em dígitos binários. O PostgreSQL aceita de float(1) a float(24) como selecionando o tipo real, enquanto float(25) a float(53) selecionam double precision. Os valores de p fora da faixa permitida ocasionam erro. float sem precisão especificada é assumido como significando double precision.

Nota: Antes do PostgreSQL 7.4 a precisão em float(p) era considerada como significando a quantidade de dígitos decimais, mas foi corrigida para corresponder ao padrão SQL, que especifica que a precisão é medida em dígitos binários. A premissa que real e double precision possuem exatamente 24 e 53 bits na mantissa, respectivamente, está correta para implementações em acordo com o padrão IEEE para números de ponto flutuante. Nas plataformas não-IEEE pode ser um pouco diferente, mas para simplificar as mesmas faixas de p são utilizadas em todas as plataformas.

8.1.4. Tipos seriais

Os tipos de dado serial e bigserial não são tipos verdadeiros, mas meramente uma notação conveniente para definir colunas identificadoras únicas (semelhante à propriedade AUTO_INCREMENTO existente em alguns outros bancos de dados). Na implementação corrente especificar

CREATE TABLE nome_da_tabela (
    nome_da_coluna SERIAL
);

equivale a especificar:

CREATE SEQUENCE nome_da_tabela_nome_da_coluna_seq;
CREATE TABLE nome_da_tabela (
    nome_da_coluna integer DEFAULT nextval('nome_da_tabela_nome_da_coluna_seq') NOT NULL
);

Conforme visto, foi criada uma coluna do tipo inteiro e feito o valor padrão ser atribuído a partir de um gerador de seqüência. A restrição NOT NULL é aplicada para garantir que não pode ser inserido o valor nulo explicitamente. Na maior parte das vezes, deve ser colocada uma restrição UNIQUE ou PRIMARY KEY para não permitir a inserção de valores duplicados por acidente, mas isto não é automático.

Nota: Antes do PostgreSQL 7.3 serial implicava UNIQUE, mas isto não é mais automático. Se for desejado que a coluna serial esteja em uma restrição de unicidade ou de chave primária isto deve ser especificado, da mesma forma como em qualquer outro tipo de dado.

Para inserir o próximo valor da seqüência em uma coluna do tipo serial deve ser especificada a atribuição do valor padrão à coluna serial, o que pode ser feito omitindo a coluna na lista de colunas no comando INSERT, ou através da utilização da palavra chave DEFAULT.

Os nomes de tipo serial e serial4 são equivalentes: ambos criam colunas do tipo integer. Os nomes de tipo bigserial e serial8 funcionam da mesma maneira, exceto por criarem uma coluna bigint. Deve ser utilizado bigserial se forem esperados mais de 231 identificadores durante a existência da tabela.

A seqüência criada para a coluna do tipo serial é removida automaticamente quando a coluna que a definiu é removida, e não pode ser removida de outra forma (Isto não era verdade nas versões do PostgreSQL anteriores a 7.3. Deve ser observado que este vínculo de remoção automática não ocorre em uma seqüência criada pela restauração da cópia de segurança de um banco de dados pré-7.3; a cópia de segurança não contém as informações necessárias para estabelecer o vínculo de dependência). Além disso, a dependência entre a seqüência e a coluna é feita apenas para a própria coluna serial; se qualquer outra coluna fizer referência à seqüência (talvez chamando manualmente a função nextval()), haverá rompimento se a seqüência for removida. Esta forma de utilizar as seqüências das colunas serial é considerada um estilo ruim. Se for desejado suprir várias colunas a partir do mesmo gerador de seqüência, a seqüência deve ser criada como um objeto independente.

Exemplo 8-2. Alteração da seqüência da coluna serial

A seqüência criada para a coluna do tipo serial pode ter seus parâmetros alterados através do comando ALTER SEQUENCE, da mesma forma que qualquer outra seqüência criada através do comando CREATE SEQUENCE. Este exemplo mostra como proceder para fazer com que o valor inicial da coluna do tipo serial seja igual a 1000. [7]

=> CREATE TABLE t ( c1 SERIAL, c2 TEXT);

NOTA:  CREATE TABLE irá criar a seqüência implícita "t_c1_seq" para a coluna "serial" "t.c1"
CREATE TABLE

=> \ds

             Lista de relações
 Esquema |   Nome   |   Tipo    |   Dono
---------+----------+-----------+----------
 public  | t_c1_seq | seqüência | postgres
(1 linha)

=> ALTER SEQUENCE t_c1_seq RESTART WITH 1000;

=> INSERT INTO t VALUES (DEFAULT, 'Primeira linha');

=> SELECT * FROM t;

  c1  |       c2
------+----------------
 1000 | Primeira linha
(1 linha)

Notas

[1]

O SQL suporta três modalidades de tipos de dado: tipos de dado pré-definidos, tipos construídos e tipos definidos pelo usuário. Os tipos pré-definidos são algumas vezes chamados de "tipos nativos", mas não neste Padrão Internacional. Os tipos definidos pelo usuário podem ser definidos por um padrão, por uma implementação, ou por um aplicativo.

O tipo construído é especificado utilizando um dos construtores de tipo de dado do SQL: ARRAY, MULTISET, REF e ROW. O tipo construído é um tipo matriz, um tipo multi-conjunto, um tipo referência ou um tipo linha, se for especificado por ARRAY, MULTISET, REF e ROW, respectivamente. Os tipos matriz e multi-conjunto são conhecidos genericamente como tipos coleção.

(ISO-ANSI Working Draft) Foundation (SQL/Foundation), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-2:2003 (E) (N. do T.)

[2]

Todo tipo de dado inclui um valor especial, chamado de valor nulo, algumas vezes denotado pela palavra chave NULL. Este valor difere dos demais valores com relação aos seguintes aspectos.

— Uma vez que o valor nulo está presente em todo tipo de dado, o tipo de dado do valor nulo implicado pela palavra chave NULL não pode ser inferido; portanto NULL pode ser utilizado para denotar o valor nulo apenas em certos contextos, e não em todos os lugares onde um literal é permitido.

— Embora o valor nulo não seja igual a qualquer outro valor, nem seja não igual a qualquer outro valor - é desconhecido se é igual ou não a qualquer outro valor - em alguns contextos, valores nulos múltiplos são tratados juntos; por exemplo, a <cláusula group by> trata todos os valores nulos juntos.

(ISO-ANSI Working Draft) Framework (SQL/Framework), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-1:2003 (E) (N. do T.)

[3]

literal — um valor usado exatamente da forma como é visto. Por exemplo, o número 25 e a cadeia de caracteres "Alô" são ambos literais. Os literais podem ser utilizados em expressões, e podem ser atribuídos literais para constantes ou variáveis no Visual Basic. Microsoft Glossary for Business Users (N. do T.)

[4]

deprecated — Dito de um programa ou funcionalidade que é considerada em obsolescência e no processo de ter sua utilização gradualmente interrompida, geralmente em favor de uma determinada substituição. As funcionalidades em obsolescência podem, infelizmente, demorar muitos anos para desaparecer. The Jargon File (N. do T.)

[5]

Padrão americano: o ponto, e não a vírgula, separando a parte fracionária. (N. do T.)

[6]

Exemplo escrito pelo tradutor, não fazendo parte do manual original.

[7]

Exemplo escrito pelo tradutor, não fazendo parte do manual original.

SourceForge.net Logo CSS válido!