También tenga en cuenta que a menudo hay una gran diferencia entre un CHAR y un VARCHAR al hacer comparaciones de índices
¿Esto aplica / todavía aplica para Postgres?
Encontré páginas en Oracle que afirman que CHARes más o menos un alias VARCHARy, por lo tanto, el rendimiento del índice es el mismo, pero no encontré nada definitivo en Postgres.
CHARy VARCHARse implementan exactamente igual en Postgres (y Oracle). No hay diferencia en la velocidad cuando se usan esos tipos de datos.
Sin embargo, hay una diferencia que puede marcar una diferencia en el rendimiento: una charcolumna siempre se rellena a la longitud definida. Entonces, si define una columna como char(100)y una comovarchar(100) pero solo almacena 10 caracteres en cada una, la char(100)columna usa 100 caracteres para cada valor (los 10 caracteres que almacenó, más 90 espacios), mientras que la varcharcolumna solo almacena 10 caracteres.
Comparar 100 caracteres con 100 caracteres será más lento que comparar 10 caracteres con 10 caracteres, aunque dudo que pueda medir esta diferencia en una consulta SQL.
Si declara ambos con la longitud de 10 caracteres y siempre almacena exactamente 10 caracteres en ellos, entonces no hay absolutamente ninguna diferencia (esto es cierto para Oracle y Postgres)
Entonces, la única diferencia es el relleno que se hace para el chartipo de datos.
También tenga en cuenta que a menudo hay una gran diferencia entre un CHAR y un VARCHAR al hacer comparaciones de índices
La cita anterior solo es cierta si (y solo si) la charcolumna se define demasiado amplia (es decir, está desperdiciando espacio debido al relleno). Si la longitud de la charcolumna siempre se usa completamente (por lo que no se produce relleno), entonces la cita anterior es incorrecta (al menos para Postgres y Oracle)
Desde mi punto de vista, el chartipo de datos realmente no tiene ningún uso de palabras reales. Simplemente use varchar(o texten Postgres) y olvide que charexiste.
Comparar 100 caracteres con 100 caracteres será más lento que comparar 10 caracteres con 10 caracteres, aunque dudo que pueda medir esta diferencia en una consulta SQL. - Dependiendo de lo que haga la consulta además de ordenar, la diferencia puede ser enorme. Es por eso que Postgres 9.5 tiene una nueva característica de "claves abreviadas": pgeoghegan.blogspot.de/2015/01/…
chirlu
6
Estoy de acuerdo con todo lo dicho por a_horse_with_no_name, y generalmente estoy de acuerdo con el comentario de Erwin:
No, char es inferior (y anticuado). text y varchar realizan (casi) lo mismo.
Metadatos
Con una pequeña excepción, el único momento que uso char()es cuando quiero que los metadatos digan que DEBE tener caracteres x. Aunque sé que char()solo se queja si la entrada está por encima del límite, con frecuencia protegeré contra los bajos fondos en una CHECKrestricción. Por ejemplo,
CREATETABLE foo (
x char(10)CHECK( length(x)=10));INSERTINTO foo VALUES(repeat('x',9));
Hago esto por algunas razones,
char(x)a veces se infiere con los cargadores de esquemas como una columna de ancho fijo. Esto puede marcar la diferencia en un lenguaje optimizado para cadenas de ancho fijo.
Establece una convención que tiene sentido y se aplica fácilmente. Puedo escribir un cargador de esquemas en un lenguaje para generar código a partir de esta convención.
Necesito un ejemplo de dónde puedo hacer esto,
Abreviaturas de estado de dos letras, aunque debido a que esta lista se puede enumerar, normalmente lo haré con un ENUM .
Tenga en cuenta que algunas personas pueden sentirse incómodas con la incongruencia de los mensajes de error en ambos lados del límite, pero no me molesta
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)
Contrastar con varchar
Además, creo que la sugerencia anterior encaja muy bien con una convención de uso casi siempretext . Usted pregunta por eso varchar(n)también. Yo nunca uso eso . Al menos, no recuerdo la última vez que lo usé varchar(n).
Si una especificación tiene un campo de ancho estático en el que confío, utilizo char(n) ,
De lo contrario, uso textcual es efectivamente varchar(sin límite)
Si encontrara una especificación que tuviera claves de texto de longitud variable que fueran significativas y confiara en tener una longitud máxima constante, usaría varchar(n) también la . Sin embargo, no puedo pensar en nada que se ajuste a ese criterio.
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*
Oráculo
SQL>createtable x ( y char(2));Table created.
SQL>insertinto x values('Y');1row created.
SQL>select'*'|| y ||'*'from x;'*'|----*Y *
Estoy de acuerdo con todo lo dicho por a_horse_with_no_name, y generalmente estoy de acuerdo con el comentario de Erwin:
Metadatos
Con una pequeña excepción, el único momento que uso
char()
es cuando quiero que los metadatos digan que DEBE tener caracteres x. Aunque sé quechar()
solo se queja si la entrada está por encima del límite, con frecuencia protegeré contra los bajos fondos en unaCHECK
restricción. Por ejemplo,Hago esto por algunas razones,
char(x)
a veces se infiere con los cargadores de esquemas como una columna de ancho fijo. Esto puede marcar la diferencia en un lenguaje optimizado para cadenas de ancho fijo.Necesito un ejemplo de dónde puedo hacer esto,
ENUM
.En errores
Tenga en cuenta que algunas personas pueden sentirse incómodas con la incongruencia de los mensajes de error en ambos lados del límite, pero no me molesta
Contrastar con
varchar
Además, creo que la sugerencia anterior encaja muy bien con una convención de uso casi siempre
text
. Usted pregunta por esovarchar(n)
también. Yo nunca uso eso . Al menos, no recuerdo la última vez que lo usévarchar(n)
.char(n)
,text
cual es efectivamentevarchar
(sin límite)Si encontrara una especificación que tuviera claves de texto de longitud variable que fueran significativas y confiara en tener una longitud máxima constante, usaría
varchar(n)
también la . Sin embargo, no puedo pensar en nada que se ajuste a ese criterio.Notas adicionales
char
No debe confundirse con"char"
el tipo de un byte que ofrece un rendimiento sólido y beneficios de ahorro de espacio.Preguntas y respuestas relacionadas:
fuente
Postgresql
Oráculo
Postgresql no rellenó con espacios.
fuente
SELECT pg_column_size(y) FROM x;
Encontré esto más útil, y una explicación rápida de 3 líneas:
fuente