Tengo algunas bases de datos creadas usando Entity Framework Code First; las aplicaciones funcionan y, en general, estoy bastante contento con lo que Code First me permite hacer. Soy un programador primero, y un DBA segundo, por necesidad. Estoy leyendo sobre DataAttributes para describir mejor en C # lo que quiero que haga la base de datos; y mi pregunta es: ¿qué penalidad estaré comiendo al tener estas nvarchar(max)
cadenas en mi mesa (ver ejemplo a continuación)?
Hay varias columnas en esta tabla en particular; en C # se definen como tales:
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public string Message { get; set; }
public string Source { get; set; }
public DateTime Generated { get; set; }
public DateTime Written { get; set; }
Espero consultar y / u ordenar según el Nombre, Fuente, Generado y Escrito. Espero que Nombre y Fuente tengan una longitud de 0-50 caracteres, ocasionalmente hasta 150. Espero que esta tabla comience bastante pequeña (<100k filas), pero crezca significativamente con el tiempo (> 1m filas). Obviamente, el mensaje puede ser pequeño o grande, y probablemente no será consultado.
Lo que quiero saber, ¿hay un impacto de rendimiento para mis columnas de Nombre y Fuente que se definen como nvarchar(max)
cuando nunca espero que tengan más de 150 caracteres?
[MaxLength]
o[StringLength]
atributos. Algunos posibles factores negativos adicionales de columnas demasiado anchas se mencionan en la respuesta de @ PaulWhite aquívarchar(max)
todas partes perjudica su rendimiento , ¡no lo haga! Use los tipos de datos apropiados: ¡ Úselovarchar(max)
SOLO si REALMENTE necesita más de 8000 caracteres! (¡Nunca he visto el nombre o el correo electrónico de una persona tan largo!) - Vea ¿Cuál es el punto de usar VARCHAR (n)? para más informaciónRespuestas:
Los elementos de datos nvarchar (máx.) Más grandes (más de 8000 bytes) se extenderán al almacenamiento de texto y requerirán E / S adicionales. Los artículos más pequeños se almacenarán en fila. Hay opciones que controlan este comportamiento; consulte este artículo de MSDN para obtener más detalles.
Si se almacena en fila, no hay una sobrecarga de rendimiento de E / S significativa; puede haber una sobrecarga adicional de la CPU al procesar el tipo de datos, pero es probable que esto sea menor.
Sin embargo, dejar columnas nvarchar (max) alrededor de la base de datos donde no se necesitan es una forma bastante pobre. Tiene cierta sobrecarga de rendimiento y, a menudo, los tamaños de datos son bastante útiles para comprender una tabla de datos; por ejemplo, una columna varchar de 50 o 100 caracteres de ancho probablemente sea una descripción o un campo de texto libre donde uno es (digamos) 10- Es probable que 20 caracteres sean un código. Te sorprendería el significado que a menudo se tiene que inferir de una base de datos a través de suposiciones como esta.
Trabajar en el almacenamiento de datos, casi siempre en sistemas heredados mal respaldados o documentados, tener un esquema de base de datos que sea fácil de entender es bastante valioso. Si piensa en la base de datos como el legado de la aplicación, trate de ser amable con las personas que la heredarán de usted.
fuente
Aunque esto no responde a su pregunta específica, puede evitar que tenga que hacer la pregunta en primer lugar: es posible establecer una longitud en sus variables de cadena en su clase de modelo C #, lo que hará que Entity Framework genere SQL que utiliza un tipo nvarchar de longitud fija (p
nvarchar(50)
. ej. ), en lugar denvarchar(max)
.Por ejemplo, en lugar de:
Puedes usar:
También puede forzar que el tipo sea en
varchar
lugar denvarchar
, si lo desea, de la siguiente manera:Fuente: https://stackoverflow.com/questions/7341783/entity-framework-data-annotations-set-stringlength-varchar/7341920
fuente
varchar(50)
), pero EF 6 requiere lo que hay en esta respuesta.Indexando la mayor preocupación. De BOL:
Si no puede indexar correctamente, tendrá consultas lentas. Y desde una perspectiva de integridad de datos, tener
nvarchar(max)
permitirá que se coloquen más datos incorrectos en un campo que especificar el límite.fuente
Sí, el comportamiento predeterminado de EF en la asignación
string
anvarchar(max)
no es bueno. En EF 6 puede agregar su propia convención personalizada para anular este comportamiento con su propia asignación predeterminada preferida.Anular
OnModelCreating
como se indica arriba cambiará la asignación predeterminada para todas las cadenas avarchar(200)
.fuente
the default EF behavior in mapping string to nvarchar(max) is not good
Esta parece ser tu opinión generalizada. ¿Puedes explicar por qué esto no es bueno? ¿O cree que EF no es un marco para aplicaciones empresariales en las que necesita trabajar con varios idiomas? Porque ese es el tipo de columna deseado para manejar múltiples idiomas en la base de datos.max
es horrible. Pero si desea manejar varios idiomas (y sus diferentes conjuntos de caracteres) debe usarnvarchar
¿me equivoco?