Eu tenho alguns bancos de dados criados usando o Entity Framework Code First; os aplicativos estão funcionando e, em geral, estou muito feliz com o que o Code First me permite fazer. Eu sou um programador primeiro, e um DBA segundo, por necessidade. Estou lendo sobre DataAttributes para descrever melhor em C # o que eu quero que o banco de dados faça; e minha pergunta é: qual penalidade vou comer ao ter essas nvarchar(max)
cordas na minha mesa (veja o exemplo abaixo)?
Existem várias colunas nesta tabela específica; em C # eles são definidos da seguinte maneira:
[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 e / ou classificar com base em Nome, Origem, Gerado e Escrito. Espero que Nome e Origem tenham entre 0 e 50 caracteres, ocasionalmente até 150. Espero que esta tabela comece muito pequena (<100k linhas), mas cresça significativamente ao longo do tempo (> 1m linhas). Obviamente, a mensagem pode ser pequena ou grande e provavelmente não será consultada.
O que eu quero saber é que há um impacto no desempenho das minhas colunas Nome e Origem sendo definidas como nvarchar(max)
quando eu nunca espero que elas tenham mais de 150 caracteres?
[MaxLength]
ou[StringLength]
atributos. Alguns fatores negativos possíveis adicionais de colunas demasiado largas são mencionados na resposta de @ PaulWhite aquivarchar(max)
qualquer lugar prejudica seu desempenho - não faça isso! Use tipos de dados apropriados - usevarchar(max)
SOMENTE se você REALMENTE precisar de mais de 8000 caracteres! (Nunca vi tanto o nome ou o email de uma pessoa!) - Veja Qual é o sentido de usar o VARCHAR (n) mais? para mais informaçõesRespostas:
Itens de dados nvarchar (máx.) Maiores (acima de 8000 bytes) serão transferidos para o armazenamento de texto e exigirão E / S adicionais. Os itens menores serão armazenados em linha. Existem opções que controlam esse comportamento - consulte este artigo do MSDN para obter mais detalhes.
Se armazenado na linha, não há sobrecarga significativa no desempenho de E / S; pode haver sobrecarga adicional da CPU no processamento do tipo de dados, mas é provável que isso seja menor.
No entanto, deixar as colunas nvarchar (max) espalhadas pelo banco de dados onde elas não são necessárias é uma forma bastante ruim. Ele tem alguma sobrecarga de desempenho e, muitas vezes, os tamanhos de dados são bastante úteis para entender uma tabela de dados - por exemplo, uma coluna varchar de 50 ou 100 caracteres de largura provavelmente é uma descrição ou um campo de texto livre onde um que é (digamos) 10- É provável que 20 caracteres sejam um código. Você ficaria surpreso com o significado que muitas vezes é necessário deduzir de um banco de dados através de suposições como esta.
Trabalhar em data warehousing, sempre que não em sistemas legados com suporte insuficiente ou documentado, ter um esquema de banco de dados fácil de entender é bastante valioso. Se você pensa no banco de dados como legado do aplicativo, tente ser gentil com as pessoas que o herdarão.
fonte
Embora isso não responda à sua pergunta específica, pode impedir que você precise fazer a pergunta em primeiro lugar: É possível definir um comprimento nas suas variáveis de string na classe do modelo C #, o que fará com que o Entity Framework gere SQL que usa um tipo nvarchar de comprimento fixo (por exemplo
nvarchar(50)
), em vez denvarchar(max)
.Por exemplo, em vez de:
Você pode usar:
Você também pode forçar o tipo a ser, em
varchar
vez denvarchar
, se desejado, da seguinte maneira:Origem: /programming/7341783/entity-framework-data-annotations-set-stringlength-varchar/7341920
fonte
varchar(50)
), mas o EF 6 exige o que há nessa resposta.Indexando a maior preocupação. Partida BOL:
Se você não conseguir indexar corretamente, terá consultas lentas. E, do ponto de vista da integridade dos dados, ter
nvarchar(max)
permitirá que mais dados ruins sejam inseridos em um campo do que especificar o limite.fonte
Sim, o comportamento EF padrão no mapeamento
string
paranvarchar(max)
não é bom. No EF 6, você pode adicionar sua própria convenção personalizada para substituir esse comportamento pelo seu próprio mapeamento padrão preferido.A substituição
OnModelCreating
como acima mudará o mapeamento padrão de todas as strings paravarchar(200)
.fonte
the default EF behavior in mapping string to nvarchar(max) is not good
essa parece ser sua opinião generalizada. você pode explicar por que isso não é bom? Ou, você acha que a EF não é uma estrutura para aplicativos de negócios em que você precisa trabalhar com vários idiomas? Porque esse é o tipo de coluna desejado para lidar com vários idiomas no banco de dados.max
é horrível. Mas se você quiser lidar com vários idiomas (e seus diferentes conjuntos de caracteres), precisará usarnvarchar
Estou errado?