En SQL Server 2005, ¿hay alguna desventaja en hacer que todos los campos de caracteres sean nvarchar (MAX) en lugar de especificar una longitud explícitamente, por ejemplo, nvarchar (255)? (Aparte del obvio que no puede limitar la longitud del campo en el nivel de la base de datos)
sql
sql-server
sql-server-2005
Stucampbell
fuente
fuente
Respuestas:
La misma pregunta se hizo en los foros de MSDN:
De la publicación original (mucha más información allí):
fuente
N/VARCHAR(MAX)
" porque hay un procesamiento adicional "solo si el tamaño supera los 8000". Por lo tanto, incurre en el costo solo cuando es necesario y su base de datos es menos restrictiva . ¿Estoy leyendo esto mal? Parece que casi siempre querrías enN/VARCHAR(MAX)
lugar deN/VARCHAR(1-8000)
...sp_tableoptions
: msdn.microsoft.com/en-us/library/ms173530.aspx . Los tipos VARCHAR (255) también se pueden eliminar de la fila, la 'sobrecarga' mencionada puede ser exactamente la misma para MAX y 255. Compara los tipos MAX con los tipos TEXT, cuando son distintos a medida que se obtiene (API completamente diferente para manipular, almacenamiento diferente, etc.). No menciona las diferencias reales: sin índice, sin operaciones en línea en los tipos MAXEs una pregunta justa y él dijo aparte de lo obvio ...
Las desventajas pueden incluir:
Implicaciones de rendimiento El optimizador de consultas utiliza el tamaño del campo para determinar el plan de ejecución más eficiente
"1. La asignación de espacio en extensiones y páginas de la base de datos es flexible. Por lo tanto, al agregar información al campo mediante la actualización, su base de datos tendría que crear un puntero si los nuevos datos son más largos que los insertados anteriormente. fragmentarse = menor rendimiento en casi todo, desde el índice hasta eliminar, actualizar e insertar ". http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx
Implicaciones de integración: difícil para otros sistemas saber cómo integrarse con su base de datos Crecimiento impredecible de datos Posibles problemas de seguridad, por ejemplo, podría bloquear un sistema al ocupar todo el espacio en disco
Hay un buen artículo aquí: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html
fuente
varchar(max)
.Según el enlace proporcionado en la respuesta aceptada, parece que:
Los 100 caracteres almacenados en un
nvarchar(MAX)
campo se almacenarán de forma diferente a los 100 caracteres en unnvarchar(100)
campo: los datos se almacenarán en línea y no tendrá la sobrecarga de leer y escribir datos "fuera de fila". Así que no te preocupes allí.Si el tamaño es superior a 4000, los datos se almacenarán 'fuera de fila' automáticamente, que es lo que desearía. Así que tampoco te preocupes.
Sin embargo...
nvarchar(MAX)
columna. Puede usar la indexación de texto completo, pero no puede crear un índice en la columna para mejorar el rendimiento de la consulta. Para mí, esto cierra el trato ... es una desventaja definitiva usar siempre nvarchar (MAX).Conclusión:
Si desea una especie de "longitud de cadena universal" en toda su base de datos, que pueda indexarse y que no desperdicie espacio y tiempo de acceso, puede utilizarla
nvarchar(4000)
.fuente
nvarchar(max)
todo el tiempo, comostring
en C #? - pero el punto 3) (la cuestión del índice) está dando la respuesta.nvarchar(4000)
A veces desea que el tipo de datos imponga cierto sentido a los datos que contiene.
Digamos, por ejemplo, que tiene una columna que realmente no debería tener más de 20 caracteres. Si define esa columna como VARCHAR (MAX), alguna aplicación no autorizada podría insertar una cadena larga en ella y nunca lo sabría, o tendría alguna forma de evitarlo.
La próxima vez que su aplicación use esa cadena, bajo el supuesto de que la longitud de la cadena es modesta y razonable para el dominio que representa, experimentará un resultado impredecible y confuso.
fuente
Revisé algunos artículos y encontré un script de prueba útil de esto: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Luego lo cambié para comparar entre NVARCHAR (10) vs NVARCHAR (4000) vs NVARCHAR (MAX ) y no encuentro la diferencia de velocidad cuando uso números especificados pero cuando uso MAX. Puedes probar por ti mismo. Espero que esto ayude.
fuente
Piense en ello como un nivel más de seguridad. Puede diseñar su tabla sin relaciones de clave externa, perfectamente válida, y garantizar la existencia de entidades asociadas completamente en la capa empresarial. Sin embargo, las claves foráneas se consideran buenas prácticas de diseño porque agregan otro nivel de restricción en caso de que algo se confunda en la capa empresarial. Lo mismo ocurre con la limitación de tamaño de campo y no con varchar MAX.
fuente
Una razón para NO usar los campos max o text es que no puede realizar reconstrucciones de índices en línea, es decir, RECONSTRUIR CON ONLINE = ON incluso con SQL Server Enterprise Edition.
fuente
El único problema que encontré fue que desarrollamos nuestras aplicaciones en SQL Server 2005, y en un caso, tenemos que admitir SQL Server 2000. Acabo de enterarme, por las malas que a SQL Server 2000 no le gusta la opción MAX para varchar o nvarchar
fuente
Mala idea cuando sabes que el campo estará en un rango establecido: de 5 a 10 caracteres, por ejemplo. Creo que solo usaría max si no estuviera seguro de cuál sería la longitud. Por ejemplo, un número de teléfono nunca tendrá más de un cierto número de caracteres.
¿Puede decir honestamente que no está seguro acerca de los requisitos de longitud aproximada para cada campo en su tabla?
Sin embargo, entiendo su punto: hay algunos campos que sin duda consideraría usar varchar (max).
Curiosamente, los documentos de MSDN lo resumen bastante bien:
Hay una discusión interesante sobre el tema aquí .
fuente
El trabajo de la base de datos es almacenar datos para que la empresa pueda utilizarlos. Parte de hacer que los datos sean útiles es asegurarse de que sean significativos. Permitir que alguien ingrese un número ilimitado de caracteres para su nombre no garantiza datos significativos.
Construir estas restricciones en la capa empresarial es una buena idea, pero eso no asegura que la base de datos permanecerá intacta. La única forma de garantizar que no se infrinjan las reglas de datos es aplicarlas al nivel más bajo posible en la base de datos.
fuente
Un problema es que si tiene que trabajar con varias versiones de SQL Server, el MAX no siempre funcionará. Entonces, si está trabajando con bases de datos heredadas o cualquier otra situación que implique varias versiones, es mejor que tenga mucho cuidado.
fuente
Como se señaló anteriormente, es principalmente una compensación entre el almacenamiento y el rendimiento. Al menos en la mayoría de los casos.
Sin embargo, hay al menos otro factor que debe considerarse al elegir n / varchar (Max) sobre n / varchar (n). ¿Se van a indexar los datos (como, por ejemplo, un apellido)? Como la definición de MAX se considera un LOB, cualquier cosa definida como MAX no está disponible para indexar. y sin un índice, cualquier búsqueda que involucre los datos como predicado en una cláusula WHERE se verá obligada a un análisis de tabla completa, que es el peor rendimiento que puede obtener para las búsquedas de datos.
fuente
1) El servidor SQL tendrá que utilizar más recursos (memoria asignada y tiempo de CPU) cuando se trate de nvarchar (max) vs nvarchar (n) donde n es un número específico para el campo.
2) ¿Qué significa esto en lo que respecta al rendimiento?
En SQL Server 2005, consulté 13,000 filas de datos de una tabla con 15 columnas nvarchar (max). Tomé el tiempo de las consultas repetidamente y luego cambié las columnas a nvarchar (255) o menos.
Las consultas previas a la optimización promediaron 2.0858 segundos. Las consultas después del cambio regresaron en un promedio de 1.90 segundos. Eso fue aproximadamente 184 milisegundos de mejora en la consulta básica select *. Esa es una mejora del 8.8%.
3) Mis resultados coinciden con algunos otros artículos que indican que hubo una diferencia de rendimiento. Dependiendo de su base de datos y la consulta, el porcentaje de mejora puede variar. Si no tiene muchos usuarios concurrentes o muchos registros, la diferencia de rendimiento no será un problema para usted. Sin embargo, la diferencia de rendimiento aumentará a medida que aumenten más registros y usuarios concurrentes.
fuente
Tenía un udf que rellenaba cadenas y ponía la salida a varchar (max). Si esto se usó directamente en lugar de volver al tamaño apropiado para la columna que se está ajustando, el rendimiento fue muy pobre. Terminé poniendo el udf a una longitud arbitraria con una nota grande en lugar de confiar en todos los llamadores del udf para volver a lanzar la cadena a un tamaño más pequeño.
fuente
sistema de soporte heredado. Si tiene un sistema que utiliza los datos y se espera que tenga una longitud determinada, entonces la base de datos es un buen lugar para hacer cumplir la longitud. Esto no es ideal, pero los sistemas heredados a veces no lo son. = P
fuente
Si todos los datos en una fila (para todas las columnas) nunca tomaran razonablemente 8000 o menos caracteres, entonces el diseño en la capa de datos debería aplicar esto.
El motor de base de datos es mucho más eficiente manteniendo todo fuera del almacenamiento de blobs. Cuanto más pequeño pueda restringir una fila, mejor. Cuantas más filas puedas meter en una página, mejor. La base de datos funciona mejor cuando tiene que acceder a menos páginas.
fuente
Mis pruebas han demostrado que existen diferencias al seleccionar.
fuente
Enlace interesante: ¿Por qué usar un VARCHAR cuando puedes usar TEXT?
Se trata de PostgreSQL y MySQL, por lo que el análisis de rendimiento es diferente, pero la lógica de la "explicidad" sigue vigente: ¿por qué obligarse a preocuparse siempre por algo relevante un pequeño porcentaje del tiempo? Si guardó una dirección de correo electrónico en una variable, usaría una 'cadena' no una 'cadena limitada a 80 caracteres'.
fuente
La principal desventaja que puedo ver es que digamos que tienes esto:
¿Cuál le da más información sobre los datos necesarios para la interfaz de usuario?
Esta
¿O esto?
fuente
Una desventaja es que estará diseñando alrededor de una variable impredecible, y probablemente ignorará en lugar de aprovechar la estructura de datos interna de SQL Server, compuesta progresivamente de fila (s), página (s) y extensión (s).
Lo que me hace pensar en la alineación de la estructura de datos en C, y que estar al tanto de la alineación generalmente se considera una buena cosa (TM). Idea similar, contexto diferente.
Página de MSDN para páginas y extensiones
Página de MSDN para datos de desbordamiento de fila
fuente
Primero pensé en esto, pero luego volví a pensar. Hay implicaciones de rendimiento, pero igualmente sirve como una forma de documentación para tener una idea de qué tamaño son realmente los campos. Y se aplica cuando esa base de datos se encuentra en un ecosistema más grande. En mi opinión, la clave es ser permisivo pero solo dentro de lo razonable.
ok, aquí están mis sentimientos simplemente sobre el tema de la lógica de la capa de datos y negocios. Depende, si su base de datos es un recurso compartido entre sistemas que comparten lógica de negocios, entonces, por supuesto, parece un lugar natural para hacer cumplir dicha lógica, pero no es la MEJOR forma de hacerlo, la MEJOR forma es proporcionar una API, esto permite la interacción que se probará y mantendrá la lógica de negocios donde pertenece, mantiene los sistemas desacoplados, mantiene sus niveles dentro de un sistema desacoplado. Sin embargo, si se supone que su base de datos está sirviendo solo una aplicación, entonces dejemos que AGILE piense, ¿qué es verdad ahora? diseño por ahora. Si se necesita dicho acceso, proporcione una API a esos datos.
obviamente, sin embargo, este es el ideal, si está trabajando con un sistema existente, lo más probable es que deba hacerlo de manera diferente al menos a corto plazo.
fuente
Esto causará un problema de rendimiento, aunque nunca puede causar problemas reales si su base de datos es pequeña. Cada registro ocupará más espacio en el disco duro y la base de datos necesitará leer más sectores del disco si está buscando en muchos registros a la vez. Por ejemplo, un registro pequeño podría caber 50 en un sector y un registro grande podría caber en 5. Necesitaría leer 10 veces más datos del disco usando el registro grande.
fuente
nvarchar(max)
columna no ocupa más espacio en el disco que si estuviera en unanvarchar(100)
columna.Hará que el diseño de la pantalla sea más difícil, ya que ya no podrá predecir qué tan amplios deberían ser sus controles.
fuente