¿Hay alguna desventaja de usar siempre nvarchar (MAX)?

342

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)

Stucampbell
fuente
1
No entiendo por qué quieres dejar que alguien ingrese un nombre de más de 8000 caracteres.
DForck42
2
La misma lógica se puede aplicar a los lenguajes de programación. ¿Por qué no volver a la antigua variante VB6 para todos nuestros datos? No creo que tener cheques y saldos en más de un lugar sea necesariamente malo.
Matt Spradley
1
Verifique esto: stackoverflow.com/questions/2009694/…
Akira Yamamoto
10
Su actualización debe ser su propia respuesta a esta pregunta.
Johann
la respuesta en pregunta se movió a la respuesta adecuada, ya que el autor original no lo ha hecho. stackoverflow.com/a/35177895/10245 Me imagino que 7 años es tiempo suficiente :-)
Tim Abell

Respuestas:

153

La misma pregunta se hizo en los foros de MSDN:

De la publicación original (mucha más información allí):

Cuando almacena datos en una columna VARCHAR (N), los valores se almacenan físicamente de la misma manera. Pero cuando lo almacena en una columna VARCHAR (MAX), detrás de la pantalla, los datos se manejan como un valor de TEXTO. Por lo tanto, se necesita un procesamiento adicional cuando se trata de un valor VARCHAR (MAX). (solo si el tamaño supera los 8000)

VARCHAR (MAX) o NVARCHAR (MAX) se considera como un "tipo de valor grande". Los tipos de valores grandes generalmente se almacenan 'fuera de fila'. Significa que la fila de datos tendrá un puntero a otra ubicación donde se almacena el 'valor grande' ...

David Kreps
fuente
2
Entonces, la pregunta debería ser: ¿hay alguna diferencia entre usar N / VARCHAR (MAX) y N / TEXT?
cortar
18
Si recuerdo correctamente, ¿no se almacenan solo fuera de fila si el tamaño supera los 8k?
Sam Schutte
79
Leí la respuesta como "no, no hay inconveniente en usar 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 en N/VARCHAR(MAX)lugar de N/VARCHAR(1-8000)...
Kent Boogaart
1
Enlace muerto arriba: el enlace de trabajo para la pregunta en MSDN es social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/…
Jagd
68
Lamentablemente, esta respuesta tiene varios problemas. Hace que el límite de 8k parezca un número mágico, no es cierto, el valor se elimina de la fila en función de muchos más factores, incluidos 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 MAX
Remus Rusanu
50

Es 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

alexmac
fuente
44
+1 Por las implicaciones de integración y seguridad. Este es un ángulo original a considerar cuando la mayoría de las otras respuestas hablan sobre el rendimiento. En relación con las implicaciones de integración, cualquier herramienta (como los redactores de informes o los diseñadores de formularios) que usan metadatos para proporcionar tamaños de control predeterminados razonables requeriría mucho más trabajo para usar si todas las columnas lo fueran varchar(max).
Desilusionado
La integración por base de datos es lo más ridículo que sé. Si solo se realiza la importación una vez, puede verificar los datos antes con la función LEN.
Maxim
30

Según el enlace proporcionado en la respuesta aceptada, parece que:

  1. Los 100 caracteres almacenados en un nvarchar(MAX)campo se almacenarán de forma diferente a los 100 caracteres en un nvarchar(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í.

  2. 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...

  1. No puede crear un índice en una 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).

Tim Abell
fuente
1
digo, esta fue una edición agregada a la pregunta original que debería haberse publicado como respuesta
Tim Abell,
1
Gracias, para mí esta es la respuesta final. Me pregunté lo mismo, ¿por qué no usar nvarchar(max)todo el tiempo, como stringen C #? - pero el punto 3) (la cuestión del índice) está dando la respuesta.
SQL Police
1
Se agregó una edición. Como una especie de "longitud de cadena universal", siempre se puede usarnvarchar(4000)
SQL Police
@SQLGeorge Vea esta excelente respuesta de Martin Smith sobre el impacto para consultar el rendimiento de declarar columnas más amplias de lo que nunca serán
billinkc
@billinkc Gracias, ese es un gran artículo. OK, entonces el tamaño de hecho afecta el rendimiento. Editaré la respuesta nuevamente.
SQL Police
28

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.

Bill Karwin
fuente
99
Estoy de acuerdo con esto y con algunos de los otros comentarios, pero aún mantengo que es responsabilidad del nivel comercial. Para cuando llegue al nivel de la base de datos, debería saludar y almacenar el valor, sin importar cuán ridículamente largo sea. Creo que lo que está realmente en juego aquí es que pienso en el 90% del tiempo cuando un desarrollador especifica varchar (255), su intención no es realmente 255 caracteres, sino un valor de longitud medio no especificado. Y dada la compensación entre valores irrazonablemente grandes en mi base de datos y excepciones imprevistas, tomaré los valores grandes.
Chris B. Behrens
44
Si están especificando VARCHAR (255) para indicar una longitud desconocida, entonces es su culpa por no investigar adecuadamente lo que están diseñando. La solución es que el desarrollador haga su trabajo, no que la base de datos permita valores irrazonables.
Tom H
10
No es útil para el autor. excluyó explícitamente esta pregunta a la que respondiste.
usr
66
@ Chris B Behrens: no estoy de acuerdo; El esquema de la base de datos es parte de la lógica empresarial. La elección de tablas, relaciones, campos y tipos de datos es toda lógica de negocios, y vale la pena usar el RDBMS para hacer cumplir las reglas de esta lógica de negocios. Por una razón, es muy raro que solo haya un nivel de aplicación accediendo a la base de datos; por ejemplo, puede tener herramientas de importación y extracción de datos que omiten el nivel comercial principal, lo que significa que realmente necesita que la base de datos aplique las reglas.
Vince Bowdren
1
Si no necesita o desea que se almacenen cadenas largas, es mejor imponer el sentido a los datos. Por ejemplo, si almacena un campo PostCode, ¿dejaría que alguien ingrese cientos o miles de caracteres cuando debería tener un máximo de 10, digamos? El tamaño máximo debería validarse en todos los niveles, cliente, nivel comercial Y base de datos. Si usa un enfoque de Model First, como con C # y Entity Framework, puede definir su tamaño máximo en el modelo y aplicarlo a la base de datos, la lógica de negocios y la validación del cliente (con los gustos de la validación jquery). Solo use nvarchar (max) si es realmente necesario
Peter Kerr
21

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.

SET NOCOUNT ON;

--===== Test Variable Assignment 1,000,000 times using NVARCHAR(10)
DECLARE @SomeString NVARCHAR(10),
        @StartTime DATETIME;
--=====         
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
QMaster
fuente
44
Eso es interesante. En mi caja parece que el MAX es 4 veces más lento.
stucampbell
44
Nuevos resultados en SQL Server 2012: 10 es dos veces más lento que 4k y MAX es 5.5 veces más lento que 4k.
cassandrad
1
La mayoría de las veces es la conversión implícita de varchar a nvarchar (max). Pruebe este: DECLARE \ @SomeString NVARCHAR (MAX), \ @abc NVARCHAR (max) = N'ABC ', \ @StartTime DATETIME; SELECT @startTime = GETDATE (); SELECCIONE TOP 1000000 \ @SomeString = \ @abc FROM master.sys.all_columns ac1, master.sys.all_columns ac2; SELECT testTime = 'MAX', Duración = DATEDIFF (ms, \ @ StartTime, GETDATE ()); Tuve que insertar las variables \ before para que se publique.
Kvasi
44
SQL Server 2014 en SSD: 150, 156, 716 (10, 4000, MAX).
Maxim
2
Gracias por agregar algunos números reales a esta discusión. A menudo olvidamos que crear un caso de prueba es la forma más rápida de obtener información.
David C
13

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.

Alex
fuente
8

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.

Nick Kavadias
fuente
1
Esta misma restricción está vigente para el tipo de campo TEXTO, por lo que aún debe usar VARCHAR (MAX) en lugar de TEXTO.
Will Shaver
no pudimos reconstruir nuestro índice agrupado debido a esto. nos costó mucho espacio en el disco hasta que pudimos extraer la columna en su propia tabla (no pudimos permitirnos bloquear la tabla por más de 7 segundos)
Choco Smith
4

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

mattruma
fuente
2
Entonces, ¿por qué no desarrollarse en el mínimo común denominador?
binki
4

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:

Use varchar cuando los tamaños de las entradas de datos de la columna varíen considerablemente. Use varchar (max) cuando los tamaños de las entradas de datos de la columna varían considerablemente, y el tamaño puede exceder los 8,000 bytes.

Hay una discusión interesante sobre el tema aquí .

RichardOD
fuente
2
Para cosas como números de teléfono, sería mucho más agradable usar un campo char en lugar de varchar. Mientras mantenga un estándar en su almacenamiento y no tenga que preocuparse por los números de teléfono de diferentes países, nunca debería necesitar un campo variable para algo como un número de teléfono (10 sin ningún formato) o código postal (5) o 9-10 si agrega los últimos cuatro dígitos), etc.
TheTXI
Me refería a números de teléfono que pueden variar en longitud. Quizás debería poner esto en la respuesta. Cualquier cosa que tenga una longitud fija, usaría un campo char.
RichardOD
O tal vez debería haber dicho en mi comentario nchar o char. :-)
RichardOD
2
El número de caracteres en un número de teléfono es prácticamente un requisito comercial. Si se le solicitara que almacenara el código estándar internacional junto con el número, podría ser más de 10. O, alguna parte del mundo podría tener más de 10 dígitos para un número de teléfono. Imagine el caso de la transición de IPV4 a IPV6. Nadie habría argumentado que necesitábamos más de 12 dígitos en los viejos tiempos de IPV4. Es posible que no se mantenga bien si IPV6 se vuelve frecuente. Esto es nuevamente un cambio en la regla de negocios durante un período de tiempo. Como se dice, el cambio es la única cosa constante que podemos esperar :)
pencilslate
2
Tenga cuidado al asumir que sabe cuántos caracteres pueden estar en un campo de número de teléfono, o qué tipo de caracteres serán. A menos que el sistema use esos datos para marcar realmente (en cuyo caso debe ser estricto con los formatos), entonces el usuario podría legítimamente colocar cadenas inesperadamente largas, por ejemplo, "0123 456 78910 solicitar la recepción de la extensión 45 y luego transferir a James".
Vince Bowdren
4

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.

Tom H
fuente
66
En mi opinión, las limitaciones de longitud de datos se basan exclusivamente en las reglas de negocio, que pueden cambiar durante un período de tiempo, a medida que la aplicación crece. Cambiar las reglas de negocios en la lógica de negocios es más fácil que en el nivel de base de datos. Por lo tanto, creo que el PP debe ser lo suficientemente flexible y no debe ser atado a las reglas de negocio como el máximo permitido longitud del nombre de pila, que es muy dependiente tanto de la parte del mundo donde se vive en sus usuarios.
pencilslate
3

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.

TheTXI
fuente
Creo que la suposición tácita por parte del OP es que está tratando completamente con más de 2005 instancias, y que sus aplicaciones no necesitarán funcionar en versiones 2000 (o, ack, inferiores). Sin embargo, estoy totalmente de acuerdo con usted si es necesario admitir las versiones anteriores.
John Rudy
John Rudy: Me imagino que ese es el caso, solo sé que me he encontrado con esos obstáculos cuando no creía que iba a hacerlo.
TheTXI
En realidad, este es un problema frecuente aún con las cosas modernas debido a SQL CE 4 que no admite los tipos de columna MAX, por lo que la interoperabilidad es una molestia.
JohnC
3

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.

Harry Cooper
fuente
2

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.

WWC
fuente
1

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.

Cade Roux
fuente
1

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

Tony
fuente
1

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.

Matt Spradley
fuente
1

Mis pruebas han demostrado que existen diferencias al seleccionar.

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;
Kvasi
fuente
0

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'.

orip
fuente
1
Es similar a argumentar que no debería tener restricciones de verificación para garantizar que la edad de una persona no sea un número negativo.
Jonathan Allen
Veo una diferencia entre la corrección de datos y la optimización del rendimiento.
orip
0

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

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

¿O esto?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]
carlos martini
fuente
3
Preferiría que la lógica de negocios me dijera que el nombre de una empresa puede tener un máximo de 50 caracteres en lugar de confiar en una tabla de base de datos para esa información.
Khan
Estoy de acuerdo con Jeff No creo que la tienda de persistencia sea el lugar adecuado para definir las reglas de su negocio. Y en una arquitectura en capas, su IU ni siquiera conocería la capa de persistencia.
stucampbell
A menos que, por supuesto, esté utilizando un valor que esté restringido a un tamaño específico, por ejemplo, el código ISO para el país.
Ben
2
¿Qué tiene que ver eso con una tabla def? Todavía puedes tener lógica de negocios. Creo que su punto no tiene sentido en relación con el diseño de una tabla. Si aún desea diseñar algún tipo de definición en su capa empresarial, que así sea. Aunque lo que tendría más sentido, es utilizar un proceso almacenado de todos modos en la capa empresarial; no es una mesa def ??
carlos martini
1
Parece impopular, pero estoy de acuerdo con Carlos, si la base de datos establece un tamaño máximo, entonces puede sentirse cómodo en todas las capas que construye encima de lo que es probable que tenga que lidiar. Esto es particularmente importante si tiene múltiples sistemas escribiendo en su base de datos.
Tim Abell
0

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

tsundoku
fuente
0

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.

Stephen Whipp
fuente
-1

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.

Dan Goldstein
fuente
55
-1. Una cadena de longitud 100 almacenada en una nvarchar(max)columna no ocupa más espacio en el disco que si estuviera en una nvarchar(100)columna.
Martin Smith
Lo que está describiendo es correcto si el tamaño de los datos almacenados es mayor, pero esta pregunta es sobre si el tipo de datos tiene implicaciones de rendimiento u otras consideraciones.
-2

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.

pappes
fuente