Моя попытка обобщить и исправить существующие ответы:
Во-первых, char
и nchar
всегда будут использовать фиксированный объем пространства хранения, даже когда строка для хранения меньше доступного пространства, тогда как varchar
и nvarchar
будут использовать только столько памяти пространство, необходимое для хранения этой строки (плюс два байта служебной информации, предположительно для хранения длины строки). Помните, что «var» означает «переменная», как в переменном пространстве.
Второй важный момент, который нужно понять, заключается в том, что nchar
и nvarchar
хранят строки, используя точно два байта на символ, тогда как char
и varchar
используют кодировку, определенную кодом сопоставления страница, которая обычно будет составлять ровно один байт на символ (хотя есть исключения, см. ниже). Используя два байта на символ, можно сохранить очень широкий диапазон символов, поэтому следует помнить, что nchar
и nvarchar
имеют тенденцию быть гораздо лучшим выбором, когда вам нужна поддержка интернационализации, что вы, вероятно, делаете .
Теперь о некоторых тонких точках.
Во-первых, nchar
и nvarchar
столбцы всегда хранят данные с использованием UCS-2. Это означает, что будет использоваться ровно два байта на символ, и любой символ Юникода в базовой многоязычной плоскости (BMP) может быть сохранен в поле nchar
или nvarchar
. Однако это не тот случай, когда любой символ Unicode может быть сохранен. Например, согласно Википедии, кодовые точки для египетских иероглифов выходят за пределы BMP. Следовательно, есть строки Unicode, которые могут быть представлены в UTF-8, и другие истинные кодировки Unicode, которые не могут быть сохранены в поле SQL Server nchar
или nvarchar
, и строки, написанные в египетских иероглифах, будут среди них. К счастью, ваши пользователи, вероятно, не пишут в этом сценарии, но об этом нужно помнить!
Еще один сбивающий с толку, но интересный момент, который подчеркивали другие авторы, заключается в том, что в полях char
и varchar
могут использоваться два байта на символ для определенных символов, если этого требует кодовая страница сопоставления. (Мартин Смит приводит отличный пример, в котором он показывает, как это поведение демонстрирует Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS. Проверьте это.)
ОБНОВЛЕНИЕ: Начиная с SQL Server 2012, наконец, есть кодовые страницы для UTF-16 , например Latin1_General_100_CI_AS_SC, которые действительно могут охватывать весь диапазон Unicode.