Gardez également à l'esprit qu'il y a souvent une très grande différence entre un CHAR et un VARCHAR lors des comparaisons d'index
Est-ce que cela s'applique / s'applique toujours à Postgres?
J'ai trouvé des pages sur Oracle affirmant qu'il CHARs'agit plus ou moins d'un alias VARCHARet donc les performances de l'index sont les mêmes, mais je n'ai rien trouvé de définitif sur Postgres.
CHARet VARCHARsont implémentés exactement de la même manière dans Postgres (et Oracle). Il n'y a aucune différence de vitesse lors de l'utilisation de ces types de données.
Cependant, il existe une différence qui peut faire une différence dans les performances: une charcolonne est toujours complétée à la longueur définie. Donc, si vous définissez une colonne en tant que char(100)et une en tant que varchar(100)mais ne stockez que 10 caractères dans chacune, la char(100)colonne utilise 100 caractères pour chaque valeur (les 10 caractères que vous avez stockés, plus 90 espaces), tandis que la varcharcolonne ne stocke que 10 caractères.
Comparer 100 caractères à 100 caractères va être plus lent que comparer 10 caractères à 10 caractères - bien que je doute que vous puissiez réellement mesurer cette différence dans une requête SQL.
Si vous déclarez les deux avec une longueur de 10 caractères et que vous y stockez toujours exactement 10 caractères, il n'y a absolument aucune différence (cela est vrai pour Oracle et Postgres)
La seule différence est donc le remplissage effectué pour le chartype de données.
Gardez également à l'esprit qu'il y a souvent une très grande différence entre un CHAR et un VARCHAR lors des comparaisons d'index
La citation ci - dessus est uniquement vrai si (et seulement si) la charcolonne est définie trop large (vous perdez l' espace en raison de rembourrage). Si la longueur de la charcolonne est toujours utilisée complètement (donc aucun remplissage ne se produit), alors la citation ci-dessus est fausse (au moins pour Postgres et Oracle)
De mon point de vue, le chartype de données n'a pas vraiment d'utilisation réelle. Utilisez simplement varchar(ou textdans Postgres) et oubliez que cela charexiste.
Comparer 100 caractères à 100 caractères va être plus lent que comparer 10 caractères à 10 caractères - bien que je doute que vous puissiez réellement mesurer cette différence dans une requête SQL. - En fonction de ce que fait la requête en plus du tri, la différence peut être énorme. C'est pourquoi Postgres 9.5 a une nouvelle fonctionnalité de «touches abrégées»: pgeoghegan.blogspot.de/2015/01/…
chirlu
6
Je suis d'accord avec tout ce que dit a_horse_with_no_name, et je suis généralement d'accord avec les commentaires d'Erwin:
Non, l'omble est inférieur (et obsolète). text et varchar font (presque) la même chose.
Métadonnées
À une exception près, la seule fois que j'utilise, char()c'est quand je veux que les métadonnées disent que cela DOIT avoir des caractères x. Bien que je sache que cela char()ne se plaint que si l'entrée dépasse la limite, je vais souvent me protéger contre les sous-exécutions dans une CHECKcontrainte. Par exemple,
CREATETABLE foo (
x char(10)CHECK( length(x)=10));INSERTINTO foo VALUES(repeat('x',9));
Je le fais pour plusieurs raisons,
char(x)est parfois déduit avec les chargeurs de schéma comme étant une colonne de largeur fixe. Cela peut faire la différence dans un langage optimisé pour les chaînes de largeur fixe.
Il établit une convention qui a du sens et est facilement appliquée. Je peux écrire un chargeur de schéma dans un langage pour générer du code à partir de cette convention.
Besoin d'un exemple de l'endroit où je peux le faire,
Abréviations d'état à deux lettres, mais comme cette liste peut être énumérée, je le fais généralement avec un ENUM.
Notez que certaines personnes peuvent être mal à l'aise avec l'incongruité des messages d'erreur des deux côtés de la limite, mais cela ne me dérange pas
test=#INSERTINTO foo VALUES(repeat('x',9));
ERROR: new rowfor relation "foo" violates checkconstraint"foo_x_check"
DETAIL: Failing rowcontains(xxxxxxxxx ).
test=#INSERTINTO foo VALUES(repeat('x',11));
ERROR: value too long for type character(10)
Contraste avec varchar
De plus, je pense que la suggestion ci-dessus correspond très bien à une convention d' utilisation presque toujourstext . Vous demandez varchar(n)aussi. Je n'utilise jamais ça . Au moins, je ne me souviens pas de la dernière fois que j'ai utilisé varchar(n).
Si une spécification a un champ de largeur statique auquel je fais confiance, j'utilise char(n),
Sinon, j'utilise textce qui est effectivement varchar(pas de limite)
Si je trouvais une spécification qui avait des touches de texte de longueur variable qui étaient significatives et que je faisais confiance pour avoir une longueur maximale constante, j'utiliserais varchar(n)aussi. Cependant, je ne vois rien qui corresponde à ces critères.
sales_reporting_db=#createtable x (y char(2));CREATETABLE
sales_reporting_db=#insertinto x values('Y');INSERT01
sales_reporting_db=#select'*'|| y ||'*'from x;?column?----------*Y*
Oracle
SQL>createtable x ( y char(2));Table created.
SQL>insertinto x values('Y');1row created.
SQL>select'*'|| y ||'*'from x;'*'|----*Y *
Je suis d'accord avec tout ce que dit a_horse_with_no_name, et je suis généralement d'accord avec les commentaires d'Erwin:
Métadonnées
À une exception près, la seule fois que j'utilise,
char()
c'est quand je veux que les métadonnées disent que cela DOIT avoir des caractères x. Bien que je sache que celachar()
ne se plaint que si l'entrée dépasse la limite, je vais souvent me protéger contre les sous-exécutions dans uneCHECK
contrainte. Par exemple,Je le fais pour plusieurs raisons,
char(x)
est parfois déduit avec les chargeurs de schéma comme étant une colonne de largeur fixe. Cela peut faire la différence dans un langage optimisé pour les chaînes de largeur fixe.Besoin d'un exemple de l'endroit où je peux le faire,
ENUM
.Sur les erreurs
Notez que certaines personnes peuvent être mal à l'aise avec l'incongruité des messages d'erreur des deux côtés de la limite, mais cela ne me dérange pas
Contraste avec
varchar
De plus, je pense que la suggestion ci-dessus correspond très bien à une convention d' utilisation presque toujours
text
. Vous demandezvarchar(n)
aussi. Je n'utilise jamais ça . Au moins, je ne me souviens pas de la dernière fois que j'ai utilisévarchar(n)
.char(n)
,text
ce qui est effectivementvarchar
(pas de limite)Si je trouvais une spécification qui avait des touches de texte de longueur variable qui étaient significatives et que je faisais confiance pour avoir une longueur maximale constante, j'utiliserais
varchar(n)
aussi. Cependant, je ne vois rien qui corresponde à ces critères.Notes complémentaires
char
ici ne doit pas être confondu avec"char"
ce qui est un type à un octet et a des performances solides et des avantages d'économie d'espace.Questions et réponses connexes:
la source
Postgresql
Oracle
Postgresql n'a pas rempli d'espaces.
la source
SELECT pg_column_size(y) FROM x;
J'ai trouvé cela très utile et une explication rapide en 3 lignes:
la source