A varchar(1)
puede almacenar una cadena de longitud cero ("vacía"). A char(1)
no se puede rellenar en un solo espacio. Si esta distinción es importante para usted, puede preferir el varchar
.
Aparte de eso, un caso de uso para esto puede ser si el diseñador desea permitir la posibilidad de que se requiera un mayor número de caracteres en el futuro.
Alterar un tipo de datos de longitud fija desde char(1)
a char(2)
significa que todas las filas de la tabla deben actualizarse y cualquier índice o restricción que acceda a esta columna cayó primero.
Hacer estos cambios en una mesa grande en producción puede ser una operación extremadamente lenta que requiere tiempo de inactividad.
modificación de una columna de varchar(1)
a varchar(2)
es mucho más fácil ya que es un sólo cambian los metadatos (FK limitaciones que hacen referencia tendrá que ser eliminado y recreado la columna, pero no hay necesidad de reconstruir los índices o actualizar las páginas de datos).
Además, el ahorro de 2 bytes por fila puede no siempre materializarse de todos modos. Si la definición de fila ya es bastante larga, esto no siempre afectará al número de filas que pueden caber en una página de datos. Otro caso sería si el uso de la función de compresión en Enterprise Edition de la forma en que se almacenan los datos es completamente diferente a la mencionada en la respuesta de Mitch en cualquier caso. Tanto varchar(1)
como char(1)
terminarían almacenados de la misma manera en la región de datos cortos.
@Thomas - por ejemplo prueba esta definición de tabla.
CREATE TABLE T2
(
Code VARCHAR(1),
Foo datetime2,
Bar int,
Filler CHAR(4000),
PRIMARY KEY CLUSTERED (Code, Foo, Bar)
)
INSERT INTO T2
SELECT TOP 100000 'A',
GETDATE(),
ROW_NUMBER() OVER (ORDER BY (SELECT 0)),
NULL
FROM master..spt_values v1, master..spt_values v2
CREATE NONCLUSTERED INDEX IX_T2_Foo ON T2(Foo) INCLUDE (Filler);
CREATE NONCLUSTERED INDEX IX_T2_Bar ON T2(Bar) INCLUDE (Filler);
Para una varchar
es trivial para cambiar la definición de la columna de varchar(1)
a varchar(2)
. Este es un cambio solo de metadatos.
ALTER TABLE T2 ALTER COLUMN Code VARCHAR(2) NOT NULL
Si el cambio es char(1)
-char(2)
los siguientes pasos deben suceder.
- Suelta la PK de la tabla. Esto convierte la tabla en un montón y significa que todos los índices no agrupados deben actualizarse con el RID en lugar de la clave del índice agrupado.
- Alterar la definición de la columna. Esto significa que todas las filas se actualizan en la tabla para que
Code
ahora se almacene como char(2)
.
- Vuelva a agregar la restricción PK agrupada. Además de reconstruir el CI en sí, esto significa que todos los índices no agrupados deben actualizarse nuevamente con la clave CI como un puntero de fila en lugar de como un RID.
Veo que no existiría ningún motivo real para que la implementación * prohíba * VARCHAR (1), pero estoy preguntando si habría algún beneficio de diseño. Con respecto a su segundo punto, solo para aclarar, ¿está señalando que VARCHAR (1) puede ser una cadena vacía, pero CHAR (1) no puede? Puedo ver eso; una razón oscura para elegir VARCHAR (1) sobre CHAR (1), pero concebiblemente válido. –
"• Más fácil de definir en el idioma". - ¿puedes elborar? –
La sutileza se juega en ciertos casos de borde, 'CASE WHEN '' = ''' realmente evalúa a TRUE, es decir, espacio único = sin espacio, pero debe ser muy consciente de tales cosas. Simplemente haciendo caso omiso de un tipo de datos de mano no es realmente muy inteligente. El texto después de los dos puntos ilustra un ejemplo más sólido, que he visto en la vida real (simplemente no esas columnas específicamente). – RichardTheKiwi