PostgreSQL: diferença entre texto e varchar (variação de caracteres)

Qual é a diferença entre o tipo de dados text e o character varying (varchar) tipos de dados?

de acordo com a documentação

Se a variação de caracteres for usada sem especificação de comprimento, o tipo aceita cadeias de qualquer tamanho. Este último é uma extensão PostgreSQL.

e

Além disso, o PostgreSQL fornece o tipo de texto, que armazena cadeias de qualquer comprimento. Embora o texto do tipo não esteja na norma SQL, vários outros SQL os sistemas de gestão de bases de dados também o têm.

Qual é a diferença?

Author: the Tin Man, 2011-01-31

8 answers

Não há diferença, debaixo do capô é tudo varlena (variable length array ).

Verifique este artigo do Depesz: http://www.depesz.com/index.php/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/

Alguns destaques:

Para resumir tudo:

  • o char(n) – ocupa demasiado espaço quando lida com valores mais curtos do que n (passa-os para n), e pode levar a erros subtis por causa da adição de seguir em frente espaco, além disso, é problemático alterar o limite
  • Varchar(n) – é problemático alterar o limite no ambiente ao vivo (necessita de exclusividade ao alterar a tabela) {[[19]}
  • varchar - tal como o texto
  • texto-para mim um vencedor – sobre (n) Tipos de dados porque não tem os seus problemas, e sobre varchar – porque tem nome distinto

O artigo faz testes detalhados para mostrar que o desempenho de inserções e seleciona para todos os 4 Dados os tipos são semelhantes. Ele também dá uma olhada detalhada em formas alternativas de restringir o comprimento quando necessário. Restrições ou domínios baseados em função fornecem a vantagem do aumento instantâneo da restrição de comprimento, e com base em que a diminuição de uma restrição de comprimento de cadeia é rara, depesz conclui que uma delas é geralmente a melhor escolha para um limite de comprimento.

 560
Author: Frank Heikens, 2018-04-20 20:12:01

Como "tipos de caracteres " na documentação indica, varchar(n), char(n), e {[2] } estão todos armazenados da mesma forma. A única diferença é que são necessários ciclos extras para verificar o comprimento, se for dado, e o espaço e tempo extra necessários se for necessário enchimento para char(n).

No entanto, quando você só precisa armazenar um único caractere, há uma pequena vantagem de desempenho para usar o tipo especial {[[4]} (Mantenha as aspas-elas fazem parte do nome do tipo). Você tem acesso mais rápido ao campo, e não há sobrecarga para armazenar o comprimento.

Acabei de fazer uma tabela de 1.000.000 aleatórios "char" escolhidos a partir do alfabeto de minúsculas. Uma consulta para obter uma distribuição de frequência (select count(*), field ... group by field) leva cerca de 650 milisegundos, vs cerca de 760 nos mesmos dados usando um campo text.

 99
Author: George, 2016-08-05 08:03:48

Actualização dos parâmetros de referência para 2016 (pg9.5+)

E utilizando parâmetros de referência" puros SQL " (sem qualquer script externo)

  1. Usar qualquer string_ gerador com UTF8

  2. Principais parâmetros de referência:

    2.1. Inserir

    2.2. Seleccione comparar e contar


CREATE FUNCTION string_generator(int DEFAULT 20,int DEFAULT 10) RETURNS text AS $f$
  SELECT array_to_string( array_agg(
    substring(md5(random()::text),1,$1)||chr( 9824 + (random()*10)::int )
  ), ' ' ) as s
  FROM generate_series(1, $2) i(x);
$f$ LANGUAGE SQL IMMUTABLE;

Preparar ensaio específico (exemplos)

DROP TABLE IF EXISTS test;
-- CREATE TABLE test ( f varchar(500));
-- CREATE TABLE test ( f text); 
CREATE TABLE test ( f text  CHECK(char_length(f)<=500) );

Efectuar um teste básico:

INSERT INTO test  
   SELECT string_generator(20+(random()*(i%11))::int)
   FROM generate_series(1, 99000) t(i);

E outros testes,

CREATE INDEX q on test (f);

SELECT count(*) FROM (
  SELECT substring(f,1,1) || f FROM test WHERE f<'a0' ORDER BY 1 LIMIT 80000
) t;

... E utilizar EXPLAIN ANALYZE.

Actualizado novamente 2018 (pg10)

Pequena edição para adicionar os resultados de 2018 e reforçar as recomendações.


Resultados em 2016 e 2018

Os meus resultados, após a média, em muitas máquinas e em muitos testes:
( estatisticamente menos desvio padrão da tham).

Recomendação

  • Use text datatype,
    evite old varchar(x) porque às vezes não é um padrão, por exemplo em CREATE FUNCTION cláusulas varchar(x)varchar(y).

  • Limites expressos(com o mesmo desempenho!) com a Cláusula CHECK CREATE TABLE
    por exemplo CHECK(char_length(x)<=10).
    com uma perda negligenciável de desempenho em INSERT / UPDATE pode também controlar as gamas e a estrutura das cordas
    por exemplo:CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%')

 30
Author: Peter Krauss, 2018-06-14 10:58:52

No manual PostgreSQL

Não há diferença de desempenho entre estes três tipos, além do aumento do espaço de armazenamento ao usar o tipo acolchoado em branco, e alguns ciclos adicionais de CPU para verificar o comprimento ao armazenar em uma coluna com restrição de comprimento. Enquanto character(n) tem vantagens de desempenho em alguns outros sistemas de banco de dados, não há tal vantagem no PostgreSQL; na verdade, character (n) é geralmente o mais lento dos três por causa de seus custos adicionais de armazenamento. Na maioria situações texto ou caracteres variáveis devem ser usados em vez disso.

Normalmente uso texto

Referências: http://www.postgresql.org/docs/current/static/datatype-character.html

 26
Author: a_horse_with_no_name, 2015-11-05 14:50:22

Texto e varchar têm diferentes conversões implícitas. O maior impacto que notei foi a manipulação de espaços de fuga. Por exemplo ...

select ' '::char = ' '::varchar, ' '::char = ' '::text, ' '::varchar = ' '::text

Devolve true, false, true e não true, true, true como seria de esperar.

 10
Author: bpd, 2018-01-11 15:56:36
Na minha opinião, tem as suas vantagens. Sim, todos eles usam o mesmo tipo subjacente e tudo isso. Mas, deve-se salientar que os índices em PostgreSQL têm seu limite de tamanho de 2712 bytes por linha.

TL; DR: Se você usar text tipo sem restrição e tem índices nestas colunas, é muito possível que você atinge esse limite para algumas de suas colunas e obter o erro quando você tentar inserir dados, mas com o uso de varchar(n), você pode impedir ele.

Mais Alguns detalhes: O problema aqui é que o PostgreSQL não dá quaisquer exceções ao criar índices para text tipo ou varchar(n) onde n é maior que 2712. No entanto, ele vai dar erro quando um registro com tamanho comprimido superior a 2712 é tentado para ser inserido. Isso significa que você pode inserir 100.000 caracteres de cadeia que é composta por caracteres repetitivos facilmente porque ele será comprimido muito abaixo de 2712, mas você pode não ser capaz de inserir alguma cadeia de caracteres com 4000 caracteres porque o tamanho comprimido é superior a 2712 bytes. Usando varchar(n) onde n não é demasiado superior a 2712, estás a salvo destes erros.

 9
Author: sotn, 2018-04-11 12:04:29
Se você está usando trilhos, a formatação padrão das páginas pode ser diferente. Para os formulários de introdução de dados {[[0]}, as caixas são roláveis, mas character varying (Carris string) as caixas são de uma linha. Mostrar vistas são o tempo que for necessário.
 4
Author: Greg, 2017-03-24 02:10:55

character varying(n), varchar(n) - (ambos iguais). o valor será truncado para n caracteres sem criar um erro.

character(n), char(n) - (ambos iguais). comprimento fixo e vai preencher com espaços em branco até o final do comprimento.

text - comprimento ilimitado.

Exemplo:

Table test:
   a character(7)
   b varchar(7)

insert "ok    " to a
insert "ok    " to b
Temos os resultados:
a        | (a)char_length | b     | (b)char_length
----------+----------------+-------+----------------
"ok     "| 7              | "ok"  | 2
 0
Author: ofir_aghai, 2018-03-14 09:47:11