У меня есть несколько баз данных, созданных с использованием Entity Framework Code First; приложения работают, и в целом я очень доволен тем, что мне позволяет Code First. Я программист первый, а второй администратор по необходимости. Я читаю о DataAttributes для дальнейшего описания в C #, что я хочу, чтобы база данных делала; и мой вопрос: какое наказание я буду есть, имея эти nvarchar(max)
строки в моей таблице (см. пример ниже)?
В этой конкретной таблице есть несколько столбцов; в C # они определены так:
[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; }
Я ожидаю выполнить запрос и / или сортировку на основе имени, источника, сгенерированного и написанного. Я ожидаю, что Имя и Источник будут иметь длину 0-50 символов, иногда до 150. Я ожидаю, что эта таблица будет довольно маленькой (<100 тыс. Строк), но со временем значительно увеличится (> 1 млн. Строк). Очевидно, что сообщение может быть маленьким или большим, и, вероятно, не будет запрашиваться.
Что я хочу знать, есть ли снижение производительности для моих столбцов «Имя» и «Источник», которые определяются, nvarchar(max)
когда я никогда не ожидаю, что они будут длиннее 150 символов?
[MaxLength]
или[StringLength]
атрибуты. Некоторые дополнительные возможные негативные факторы слишком широких столбцов упоминаются в ответе @ PaulWhite здесьvarchar(max)
везде повредит вашей производительности - не делайте этого! Используйте соответствующие типы данных - используйтеvarchar(max)
ТОЛЬКО, если вам действительно нужно более 8000 символов! (Я никогда не видел, чтобы имя человека или адрес электронной почты были такими длинными!) - Смотрите, в чем смысл использования VARCHAR (n)? для получения дополнительной информацииОтветы:
Более крупные элементы данных nvarchar (max) (более 8000 байт или около того) будут перетекать в хранилище текста и потребовать дополнительного ввода-вывода. Меньшие предметы будут храниться в ряд. Есть варианты, которые управляют этим поведением - см. Эту статью MSDN для получения дополнительной информации.
При хранении в строке значительного снижения производительности ввода-вывода нет; при обработке типа данных могут возникнуть дополнительные затраты ресурсов процессора, но, скорее всего, они будут незначительными.
Однако оставлять столбцы nvarchar (max) в базе данных там, где они не нужны, довольно плохая форма. У него есть некоторые издержки производительности, и часто размеры данных весьма полезны для понимания таблицы данных - например, столбец varchar шириной 50 или 100 символов, вероятно, будет описанием или полем свободного текста, где (скажем) 10- 20 символов, вероятно, будут кодом. Вы будете удивлены, насколько много значат, что часто приходится делать из базы данных с помощью таких предположений.
Работа в хранилищах данных, зачастую не на плохо поддерживаемых или документированных устаревших системах, имеет простую для понимания схему базы данных. Если вы думаете о базе данных как о наследии приложения, постарайтесь быть милыми с людьми, которые собираются унаследовать ее от вас.
источник
Хотя это не отвечает на ваш конкретный вопрос, это может помешать вам в первую очередь задавать вопрос: можно задать длину строковых переменных в классе модели C #, что заставит Entity Framework генерировать SQL, который использует фиксированный тип nvarchar (например
nvarchar(50)
) вместоnvarchar(max)
.Например, вместо:
Вы можете использовать:
Вы также можете принудительно указать тип
varchar
вместо (nvarchar
при желании) следующим образом:Источник: /programming/7341783/entity-framework-data-annotations-set-stringlength-varchar/7341920
источник
varchar(50)
), но EF 6 требует того, что содержится в этом ответе.Индексация самая большая проблема. От BOL:
Если вы не можете правильно индексировать, у вас будут медленные запросы. И с точки зрения целостности данных, наличие
nvarchar(max)
в поле большего количества неверных данных, чем указание предела.источник
Да, поведение EF по умолчанию в отображении
string
наnvarchar(max)
не очень хорошее. В EF 6 вы можете добавить свое собственное пользовательское соглашение, чтобы переопределить это поведение с вашим собственным предпочтительным отображением по умолчанию.Переопределение,
OnModelCreating
как указано выше, изменит отображение по умолчанию для всех строк наvarchar(200)
.источник
the default EF behavior in mapping string to nvarchar(max) is not good
кажется, это ваше обобщенное мнение. Вы можете объяснить, почему это не хорошо? Или, как вы думаете, EF не является основой для бизнес-приложений, где вам нужно работать с несколькими языками? Потому что это желаемый тип столбца для работы с несколькими языками в базе данных.max
это ужасно. Но если вы хотите работать с несколькими языками (и их различными наборами символов), вам нужно использовать,nvarchar
я не прав?