Question PostgreSQL: Différence entre le texte et varchar (caractère variable)


Quelle est la différence entre le text type de données et le character varying (varchar) Types de données?

Selon La documentation

Si un caractère variable est utilisé sans spécificateur de longueur, le type accepte les chaînes de toutes tailles. Ce dernier est une extension PostgreSQL.

et

En outre, PostgreSQL ™ fournit le type de texte, qui stocke les chaînes de n'importe quelle longueur. Bien que le texte de type ne figure pas dans le standard SQL, plusieurs autres systèmes de gestion de base de données SQL l’ont également.

Alors, quelle est la différence?


450
2018-01-31 08:44


origine


Réponses:


Il n'y a pas de différence, sous le capot c'est tout varlena (tableau de longueur variable).

Consultez cet article de Depesz: http://www.depesz.com/index.php/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/

Un couple de faits saillants:

Pour tout résumer:

  • char (n) - prend trop de place lorsqu'il s'agit de valeurs plus courtes que n (les rembourre à n), et peut conduire à des erreurs subtiles en raison de l'ajout de   espaces, plus il est problématique de changer la limite
  • varchar (n) - il est problématique de changer la limite dans l'environnement live (nécessite un verrouillage exclusif lors de la modification de la table)
  • varchar - juste comme du texte
  • texte - pour moi un gagnant - over (n) types de données car il leur manque leurs problèmes, et sur varchar - parce qu'il a un nom distinct

L'article effectue des tests détaillés pour montrer que les performances des insertions et des sélections pour les 4 types de données sont similaires. Il prend également un regard détaillé sur d'autres façons de restreindre la longueur en cas de besoin. Les contraintes ou les domaines basés sur les fonctions offrent l'avantage d'une augmentation instantanée de la contrainte de longueur et, comme la réduction d'une contrainte de longueur de chaîne est rare, depesz en conclut que l'un d'entre eux est généralement le meilleur choix pour une limite de longueur.


531
2018-01-31 08:55



Comme "Types de caractères"dans la documentation souligne, varchar(n), char(n), et text sont tous stockés de la même manière. La seule différence est que des cycles supplémentaires sont nécessaires pour vérifier la longueur, le cas échéant, ainsi que l’espace et le temps supplémentaires nécessaires si le remplissage est nécessaire pour char(n).

Cependant, lorsque vous n’avez besoin que de stocker un seul caractère, l’utilisation du type spécial offre un léger avantage en termes de performances. "char" (Gardez les guillemets - ils font partie du nom du type). Vous obtenez un accès plus rapide au champ, et il n'y a pas de frais généraux pour stocker la longueur.

Je viens de faire une table de 1.000.000 au hasard "char" choisi dans l'alphabet minuscule. Une requête pour obtenir une distribution de fréquence (select count(*), field ... group by field) prend environ 650 millisecondes, contre environ 760 sur les mêmes données en utilisant un text champ.


95
2018-02-01 19:53



MISE À JOUR DES RÉFÉRENCES POUR 2016 (pg9.5 +)

Et utiliser des tests "purs SQL" (sans script externe)

  1. utiliser un string_generator avec UTF8

  2. principaux repères:

    2.1. INSÉRER

    2.2. SELECT comparant et comptant


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;

Préparer un test spécifique (exemples)

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) );

Effectuer un test de base:

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

Et d'autres tests,

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;

... Et utilise EXPLAIN ANALYZE.

MISE À JOUR EN 2018 (pg10)

petite modification pour ajouter les résultats de 2018 et renforcer les recommandations.


Résultats en 2016 et 2018

Mes résultats, après moyenne, dans de nombreuses machines et de nombreux tests: tous les mêmes
 (statistiquement moins que l'écart type).

Recommandation

  • Utilisation text Type de données,
    éviter vieux varchar(x) parce que parfois ce n'est pas une norme, par ex. dans CREATE FUNCTION clauses varchar(x)varchar(y).

  • exprimer des limites (avec le même varchar performance!) par avec CHECK clause dans le CREATE TABLE 
    par exemple. CHECK(char_length(x)<=10).
    Avec une perte de performance négligeable dans INSERT / UPDATE, vous pouvez également contrôler les plages et la structure des chaînes
    par exemple. CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%')


28
2018-04-23 02:36



Sur le manuel PostgreSQL

Il n'y a pas de différence de performance entre ces trois types, hormis l'augmentation de l'espace de stockage lors de l'utilisation du type padded vierge, et quelques cycles CPU supplémentaires pour vérifier la longueur lors du stockage dans une colonne contrainte par la longueur. Bien que character (n) présente des avantages en termes de performances dans certains autres systèmes de bases de données, PostgreSQL ™ ne présente pas un tel avantage. en fait, le caractère (n) est généralement le plus lent des trois en raison de ses coûts de stockage supplémentaires. Dans la plupart des situations, le texte ou les caractères doivent être utilisés à la place.

J'utilise habituellement du texte

Les références: http://www.postgresql.org/docs/current/static/datatype-character.html


24
2017-11-05 14:44



text et varchar ont des conversions de types implicites différentes. Le plus grand impact que j'ai remarqué est la gestion des espaces de fin. Par exemple ...

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

résultats true, false, true et pas true, true, true comme on peut s'y attendre.


7
2018-01-11 15:56



À mon avis, varchar(n) a ses propres avantages. Oui, ils utilisent tous le même type sous-jacent et tout ça. Mais, il faut souligner que les index dans PostgreSQL ont leur taille limite de 2712 octets Par rangée.

TL; DR: Si tu utilises text type sans contrainte et avoir des index sur ces colonnes, il est très possible que vous atteigniez cette limite pour certaines de vos colonnes et que vous obteniez une erreur lorsque vous essayez d'insérer des données mais avec l'utilisation de varchar(n), vous pouvez l'empêcher.

Quelques plus de détails: Le problème ici est que PostgreSQL ne donne aucune exception lors de la création d’index pour text tapez ou varchar(n) où n est supérieur à 2712. Cependant, il provoquera une erreur lorsqu'un enregistrement avec une taille compressée supérieure à 2712 est tenté d'être inséré. Cela signifie que vous pouvez facilement insérer 100 000 caractères de chaîne composés de caractères répétitifs car ils seront compressés bien en dessous de 2712 mais vous ne pourrez peut-être pas insérer de chaîne avec 4000 caractères car la taille compressée est supérieure à 2712 octets. En utilisant varchar(n) où n n'est pas trop supérieur à 2712, vous êtes à l'abri de ces erreurs.


5
2018-04-11 12:04



Plutôt OT: si vous utilisez Rails, le format standard des pages Web peut être différent. Pour les formulaires de saisie de données text les boîtes sont défilables, mais character varying(Des rails string) les boîtes sont une ligne. Afficher les vues est aussi longue que nécessaire.


4
2018-03-24 02:10



character varying(n), varchar(n) - (Les deux sont les mêmes). La valeur sera tronquée à n caractères sans générer d'erreur.

character(n), char(n) - (Les deux sont les mêmes). longueur fixe et va couvrir avec des blancs jusqu'à la fin de la longueur.

text - longueur illimitée.

Exemple:

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

insert "ok    " to a
insert "ok    " to b

Nous obtenons les résultats:

a        | (a)char_length | b     | (b)char_length
----------+----------------+-------+----------------
"ok     "| 7              | "ok"  | 2

0
2018-03-14 09:47