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.
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.
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.
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.
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
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.
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)
[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. |