Pregunta

Me doy cuenta de que se recomienda CHAR si todos mis valores son de ancho fijo.¿Y qué?¿Por qué no elegir VARCHAR para todos los campos de texto para estar seguro?

¿Fue útil?

Solución

Generalmente elige CARBONIZARSE si todas las filas tendrán cerca del mismo largo.Elegir VARCHAR cuando el la longitud varía significativamente.CHAR también puede ser un poco más rápido porque todas las filas tienen la misma longitud.

Varía según la implementación de la base de datos, pero generalmente VARCHAR utiliza uno o dos bytes más de almacenamiento (para longitud o terminación) además de los datos reales.Entonces (suponiendo que esté utilizando un conjunto de caracteres de un byte) almacene la palabra "FooBar"

  • CHAR(6) = 6 bytes (sin gastos generales)
  • VARCHAR(10) = 8 bytes (2 bytes de sobrecarga)
  • CHAR(10) = 10 bytes (4 bytes de sobrecarga)

La conclusión es CARBONIZARSE puede ser más rápido y más espacio eficiente para datos de relativamente la misma longitud (dentro de dos caracteres de diferencia de longitud).

Nota:Microsoft SQL tiene 2 bytes de sobrecarga para un VARCHAR.Esto puede variar de una base de datos a otra, pero generalmente se necesita al menos 1 byte de sobrecarga para indicar la longitud o EOL en un VARCHAR.

Como señaló Gaven en los comentarios, si está utilizando un conjunto de caracteres de longitud variable de varios bytes como UTF8, CHAR almacena la cantidad máxima de bytes necesarios para almacenar la cantidad de caracteres.Entonces, si UTF8 necesita como máximo 3 bytes para almacenar un carácter, entonces CHAR(6) se fijará en 18 bytes, incluso si solo almacena caracteres latinos.Entonces, en este caso, VARCHAR se convierte en una opción mucho mejor.

Otros consejos

Si estás trabajando conmigo y estás trabajando con Oracle, probablemente te haría usar varchar en casi todas las circunstancias.La suposición de que char utiliza menos potencia de procesamiento que varchar Puede ser cierto... por ahora... pero los motores de bases de datos mejoran con el tiempo y este tipo de regla general tiene el potencial de convertirse en un futuro "mito".

Otra cosa:Nunca he visto un problema de rendimiento porque alguien decidió optar por varchar.Aprovechará mucho mejor su tiempo escribiendo buen código (menos llamadas a la base de datos) y SQL eficiente (cómo funcionan los índices, cómo toma decisiones el optimizador, por qué exists más rápido que in generalmente...).

Pensamiento final:He visto todo tipo de problemas con el uso de CHAR, personas que buscan '' cuando deberían buscar '', o personas que buscan 'FOO' cuando deberían buscar 'FOO (un montón de espacios aquí)', o personas que no recortan los espacios en blanco finales, o errores con Powerbuilder sumando hasta 2000 espacios en blanco al valor que devuelve de un procedimiento de Oracle.

Además de los beneficios de rendimiento, CHAR se puede utilizar para indicar que todos los valores debería tener la misma longitud, por ejemplo, una columna para EE.UU.abreviaturas estatales.

Char es un poco más rápido, por lo que si tiene una columna que SABE que tendrá una longitud determinada, use char.Por ejemplo, almacenar (Hombre)/(Mujer)/(Des)conocido para el género, o 2 caracteres para un estado de EE. UU.

¿NChar o Char funcionan mejor que sus alternativas var?

Gran pregunta.La respuesta sencilla es sí en determinadas situaciones.Veamos si esto se puede explicar.

Obviamente, todos sabemos que si creo una tabla con una columna de varchar(255) (llamemos a esta columna myColumn) e inserto un millón de filas pero pongo solo unos pocos caracteres en myColumn para cada fila, la tabla será mucho más pequeña (en general número de páginas de datos que necesita el motor de almacenamiento) que si hubiera creado myColumn como char(255).Cada vez que hago una operación (DML) en esa tabla y solicito muchas filas, será más rápido cuando myColumn sea varchar porque no tengo que hacerlo. mover alrededor de todos esos espacios "extra" al final.Mover, como cuando SQL Server realiza clasificaciones internas, como durante una operación distinta o de unión, o si elige una combinación durante su plan de consulta, etc.Mover también podría significar el tiempo que lleva llevar los datos del servidor a mi PC local o a otra computadora o dondequiera que se vayan a consumir.

Pero hay algunos gastos generales al usar varchar.SQL Server tiene que usar un indicador de dos bytes (sobrecarga) para, en cada fila, saber cuántos bytes tiene myColumn de esa fila en particular.No son los 2 bytes adicionales los que presentan el problema, sino tener que "decodificar" la longitud de los datos en myColumn en cada fila.

En mi experiencia, tiene más sentido usar char en lugar de varchar en las columnas a las que se unirán las consultas.Por ejemplo, la clave principal de una tabla o alguna otra columna que será indexada.CustomerNumber en una tabla demográfica, o CodeID en una tabla de decodificación, o quizás OrderNumber en una tabla de pedidos.Al usar char, el motor de consultas puede realizar la unión más rápidamente porque puede realizar aritmética directa de punteros (de manera determinista) en lugar de tener que mover sus punteros una cantidad variable de bytes mientras lee las páginas.Sé que quizás te haya perdido en esa última frase.Las uniones en SQL Server se basan en la idea de "predicados". Un predicado es una condición.Por ejemplo myColumn = 1 o OrderNumber < 500.

Entonces, si SQL Server está realizando una declaración DML y los predicados o "claves" que se unen tienen una longitud fija (carácter), el motor de consultas no tiene que hacer tanto trabajo para hacer coincidir las filas de una tabla con las filas de otra mesa.No tendrá que averiguar cuánto tiempo están los datos en la fila y luego recorrer la cadena para encontrar el final.Todo eso lleva tiempo.

Ahora tenga en cuenta que esto puede fácilmente implementarse mal.He visto char utilizado para campos de clave principal en sistemas en línea.El ancho debe mantenerse pequeño, es decirchar(15) o algo razonable.Y funciona mejor en sistemas en línea porque generalmente solo recupera o inserta una pequeña cantidad de filas, por lo que tener que "recortar" esos espacios finales que obtendrá en el conjunto de resultados es una tarea trivial en lugar de tener que unir millones de filas de una tabla a millones de filas en otra tabla.

Otra razón por la que CHAR tiene sentido sobre varchar en sistemas en línea es que reduce las divisiones de páginas.Al usar char, esencialmente estás "reservando" (y desperdiciando) ese espacio, por lo que si un usuario llega más tarde y coloca más datos en esa columna, SQL ya le ha asignado espacio y listo.

Otra razón para utilizar CHAR es similar a la segunda razón.Si un programador o usuario realiza una actualización "por lotes" de millones de filas, agregando alguna oración a un campo de nota, por ejemplo, no recibirá una llamada de su DBA en medio de la noche preguntándose por qué sus unidades están llenas.En otras palabras, conduce a un crecimiento más predecible del tamaño de una base de datos.

Entonces, esas son 3 formas en que un sistema en línea (OLTP) puede beneficiarse de char sobre varchar.Casi nunca uso char en un escenario de almacén/análisis/OLAP porque normalmente tienes TANTOS datos que todas esas columnas de caracteres pueden sumar mucho espacio desperdiciado.

Tenga en cuenta que char puede hacer que su base de datos sea mucho más grande, pero la mayoría de las herramientas de respaldo tienen compresión de datos, por lo que sus respaldos tienden a tener aproximadamente el mismo tamaño que si hubiera usado varchar.Por ejemplo LiteSpeed ​​o RedGate SQL Backup.

Otro uso es en vistas creadas para exportar datos a un archivo de ancho fijo.Digamos que tengo que exportar algunos datos a un archivo plano para que un mainframe los lea.Es de ancho fijo (no delimitado).Me gusta almacenar los datos en mi tabla "preparada" como varchar (consumiendo así menos espacio en mi base de datos) y luego usar una vista para CAST todo a su equivalente char, con la longitud correspondiente al ancho del ancho fijo para esa columna. .Por ejemplo:

create table tblStagingTable (
pkID BIGINT (IDENTITY,1,1),
CustomerFirstName varchar(30),
CustomerLastName varchar(30),
CustomerCityStateZip varchar(100),
CustomerCurrentBalance money )

insert into tblStagingTable
(CustomerFirstName,CustomerLastName, CustomerCityStateZip) ('Joe','Blow','123 Main St Washington, MD 12345', 123.45)

create view vwStagingTable AS
SELECT CustomerFirstName = CAST(CustomerFirstName as CHAR(30)),
CustomerLastName = CAST(CustomerLastName as CHAR(30)),
CustomerCityStateZip = CAST(CustomerCityStateZip as CHAR(100)),
CustomerCurrentBalance = CAST(CAST(CustomerCurrentBalance as NUMERIC(9,2)) AS CHAR(10))

SELECT * from vwStagingTable

Esto es genial porque internamente mis datos ocupan menos espacio porque usan varchar.Pero cuando uso DTS o SSIS o incluso simplemente corto y pego desde SSMS al Bloc de notas, puedo usar la vista y obtener la cantidad correcta de espacios finales.En DTS solíamos tener una función llamada, maldita sea, lo olvidé, creo que se llamaba "sugerir columnas" o algo así.En SSIS ya no puedes hacer eso, tienes que definir tediosamente el administrador de conexión de archivos planos.Pero como ya tiene su vista configurada, SSIS puede conocer el ancho de cada columna y puede ahorrar mucho tiempo al crear sus tareas de flujo de datos.

Entonces, en resumen...utilizar varchar.Hay una cantidad muy pequeña de razones para usar char y es solo por razones de rendimiento.Si tiene un sistema con cientos de millones de filas, verá una diferencia notable si los predicados son deterministas (char), pero para la mayoría de los sistemas usar char es simplemente desperdiciar espacio.

Espero que ayude.jeff

Hay beneficios de rendimiento, pero aquí hay uno que no se ha mencionado:migración de filas.Con char, reserva todo el espacio por adelantado. Entonces, digamos que tiene un char (1000) y almacena 10 caracteres, utilizará los 1000 caracteres de espacio.En varchar2(1000), solo usarás 10 caracteres.El problema viene cuando modificas los datos.Digamos que actualiza la columna para que ahora contenga 900 caracteres.Es posible que el espacio para expandir el varchar no esté disponible en el bloque actual.En ese caso, el motor de base de datos debe migrar la fila a otro bloque y crear un puntero en el bloque original a la nueva fila en el nuevo bloque.Para leer estos datos, el motor de base de datos ahora tendrá que leer 2 bloques.
Nadie puede decir de manera equívoca que varchar o char son mejores.Hay espacio para hacer concesiones de tiempo y considerar si los datos se actualizarán, especialmente si hay buenas posibilidades de que crezcan.

Existe una diferencia entre la optimización temprana del rendimiento y el uso de un tipo de regla de mejores prácticas.Si está creando tablas nuevas donde siempre tendrá un campo de longitud fija, tiene sentido usar CHAR, debería usarlo en ese caso.No se trata de una optimización temprana, sino más bien de implementar una regla general (o mejores prácticas).

es decir.- Si tiene un campo de estado de 2 letras, utilice CHAR(2).Si tiene un campo con los nombres de los estados reales, use VARCHAR.

Elegiría varchar a menos que la columna almacene un valor fijo como el código de estado de EE. UU., que siempre tiene 2 caracteres y la lista de códigos de estados válidos de EE. UU. no cambia con frecuencia :).

En cualquier otro caso, incluso si se trata de almacenar una contraseña con hash (que tiene una longitud fija), elegiría varchar.

Por qué: la columna de tipo char siempre se completa con espacios, lo que hace que la columna mi_columna definido como char(5) con valor 'ABC' dentro de la comparación:

my_column = 'ABC' -- my_column stores 'ABC  ' value which is different then 'ABC'

FALSO.

Este característica podría provocar muchos errores irritantes durante el desarrollo y dificultar las pruebas.

CHAR ocupa menos espacio de almacenamiento que VARCHAR si todos los valores de datos en ese campo tienen la misma longitud.Ahora, tal vez en 2009, una base de datos de 800 GB sea la misma para todos los efectos que una de 810 GB si convierte los VARCHAR a CHAR, pero para cadenas cortas (1 o 2 caracteres), CHAR sigue siendo una "mejor práctica" de la industria, diría yo.

Ahora bien, si observa la amplia variedad de tipos de datos que la mayoría de las bases de datos proporcionan, incluso solo para números enteros (bit, tiny, int, bigint), HAY razones para elegir uno sobre el otro.Simplemente elegir bigint cada vez es en realidad ignorar un poco los propósitos y usos del campo.Si un campo simplemente representa la edad de una persona en años, un bigint es excesivo.Ahora bien, no es necesariamente "incorrecto", pero no es eficiente.

Pero es un argumento interesante y, a medida que las bases de datos mejoran con el tiempo, se podría argumentar que CHAR vs VARCHAR se vuelve menos relevante.

Mantengo el comentario de Jim McKeeth.

Además, la indexación y los escaneos completos de la tabla son más rápidos si su tabla solo tiene columnas CHAR.Básicamente, el optimizador podrá predecir qué tan grande es cada registro si solo tiene columnas CHAR, mientras que necesita verificar el valor de tamaño de cada columna VARCHAR.

Además, si actualiza una columna VARCHAR a un tamaño mayor que su contenido anterior, puede forzar a la base de datos a reconstruir sus índices (porque forzó a la base de datos a mover físicamente el registro en el disco).Mientras que con las columnas CHAR eso nunca sucederá.

Pero probablemente no le importe el impacto en el rendimiento a menos que su mesa sea enorme.

Recuerde las sabias palabras de Djikstra.La optimización temprana del rendimiento es la raíz de todos los males.

Mucha gente ha señalado que si conoce la longitud exacta del valor, utilizar CHAR tiene algunos beneficios.Pero si bien almacenar los estados de EE. UU. como CHAR(2) es fantástico hoy en día, cuando recibes el mensaje de ventas de que "acabamos de realizar nuestra primera venta a Australia", te encuentras en un mundo de dolor.Siempre envío para sobreestimar la longitud que creo que deberán tener los campos en lugar de hacer una suposición "exacta" para cubrir eventos futuros.VARCHAR me dará más flexibilidad en esta área.

Hay una pequeña sobrecarga de procesamiento al calcular el tamaño real necesario para un valor de columna y asignar el espacio para un Varchar, por lo que si está definitivamente seguro de cuánto tiempo será siempre el valor, es mejor usar Char y evitar el impacto.

Es el clásico equilibrio entre espacio y rendimiento.

En MS SQL 2005, Varchar (o NVarchar para idiomas que requieren dos bytes por carácter, es decir, chino) tienen una longitud variable.Si agrega a la fila después de haberla escrito en el disco duro, ubicará los datos en una ubicación no contigua a la fila original y provocará la fragmentación de sus archivos de datos.Esto afectará el rendimiento.

Entonces, si el espacio no es un problema, los Char son mejores para el rendimiento, pero si desea mantener bajo el tamaño de la base de datos, los varchars son mejores.

Creo que en su caso probablemente no haya razón para no elegir Varchar.Le brinda flexibilidad y, como han mencionado varios encuestados, el rendimiento ahora es tal que, excepto en circunstancias muy específicas, nosotros, los simples mortales (a diferencia de los administradores de bases de datos de Google) no notaremos la diferencia.

Una cosa interesante que vale la pena señalar cuando se trata de tipos de bases de datos es que sqlite (una mini base de datos popular con un rendimiento bastante impresionante) coloca todo en la base de datos como una cadena y escribe sobre la marcha.

Siempre uso VarChar y normalmente lo hago mucho más grande de lo que estrictamente necesito.P.ej.50 para el nombre, como usted dice, ¿por qué no solo para estar seguro?

Fragmentación.Char reserva espacio y VarChar no.Es posible que sea necesario dividir la página para dar cabida a la actualización a varchar.

NUNCA usaría caracteres.He tenido este debate con muchas personas y siempre mencionan el cliché de que el carbón es más rápido.Bueno yo digo, ¿cuánto más rápido?¿De qué estamos hablando aquí, milisegundos, segundos y si es así de cuántos?¿Me estás diciendo que porque alguien afirma que es unos milisegundos más rápido, deberíamos introducir toneladas de errores difíciles de corregir en el sistema?

Aquí hay algunos problemas con los que se encontrará:

Cada campo se rellenará, por lo que terminará con un código para siempre que tiene RTRIMS en todas partes.Esto también supone un enorme desperdicio de espacio en disco para los campos más largos.

Ahora digamos que tiene el ejemplo por excelencia de un campo char de solo un carácter, pero el campo es opcional.Si alguien pasa una cadena vacía a ese campo, se convierte en un espacio.Entonces, cuando otra aplicación/proceso lo consulta, obtiene un solo espacio, si no usa rtrim.Hemos tenido documentos, archivos y otros programas xml que muestran solo un espacio, en campos opcionales y dividen cosas.

Entonces, ahora debe asegurarse de pasar valores nulos y no una cadena vacía al campo char.Pero ese NO es el uso correcto de nulo.Aquí está el uso de nulo.Digamos que obtienes un archivo de un proveedor.

Nombre|Sexo|Ciudad

Bob||Los Ángeles

Si no se especifica el género, ingrese Bob, cadena vacía y Los Ángeles en la tabla.Ahora digamos que obtienes el archivo y su formato cambia y el género ya no está incluido, pero sí en el pasado.

Nombre|Ciudad

Bob|Seattle

Bueno, ahora que el género no está incluido, usaría nulo.Varchars admite esto sin problemas.

Char, por otro lado, es diferente.Siempre hay que enviar nulo.Si alguna vez envía una cadena vacía, terminará con un campo que tiene espacios.

Podría seguir y seguir con todos los errores que tuve que corregir en los caracteres y en aproximadamente 20 años de desarrollo.

Cuando se usa Varchar Values ​​SQL Server necesita 2 bytes adicionales por fila para almacenar información sobre esa columna, mientras que si usa Char no lo necesita, a menos que usted

En algunas bases de datos SQL, VARCHAR se completará hasta su tamaño máximo para optimizar las compensaciones. Esto es para acelerar los índices y escaneos completos de la tabla.

Debido a esto, no se ahorra espacio al utilizar VARCHAR(200) en comparación con CHAR(200).

El uso de CHAR (NCHAR) y VARCHAR (NVARCHAR) genera diferencias en la forma en que el servidor de la base de datos almacena los datos.El primero introduce espacios en blanco al final;He encontrado un problema al usarlo con el operador LIKE en las funciones de SQL SERVER.Entonces tengo que hacerlo seguro usando VARCHAR (NVARCHAR) todo el tiempo.

Por ejemplo, si tenemos una mesa PRUEBA(ID INT, Estado CHAR(1)), y escribe una función para enumerar todos los registros con algún valor específico como el siguiente:

CREATE FUNCTION List(@Status AS CHAR(1) = '')
RETURNS TABLE
AS
RETURN
SELECT * FROM TEST
WHERE Status LIKE '%' + @Status '%'

En esta función esperamos que cuando pongamos el parámetro predeterminado la función devuelva todas las filas, pero en realidad no es así.Cambie el tipo de datos @Status a VARCHAR para solucionar el problema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top