В чем разница между char, nchar, varchar и nvarchar в SQL Server?

Что подразумевается под nvarchar?

В чем разница между char, nchar, varchar и nvarchar в SQL Server?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
648
0
609 314
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

nchar и char почти так же работают друг с другом, как nvarchar и varchar. Единственное различие между ними заключается в том, что nchar / nvarchar хранят символы Unicode (что необходимо, если вам требуется использование расширенных наборов символов), а varchar - нет.

Поскольку для символов Юникода требуется больше места для хранения, поля nchar / nvarchar занимают вдвое больше места (так, например, в более ранних версиях SQL Server максимальный размер поля nvarchar составляет 4000).

Этот вопрос дублирует Вот этот.

Вы забываете одну вещь: nchar использует фиксированную длину, поэтому nchar (10) всегда должен получать десять символов. И varchar (10) действительно является Unicode и принимает любое количество символов, до 10 символов. Также см. msdn.microsoft.com/en-us/library/ms186939.aspx

Wim ten Brink 02.11.2009 13:29

nchar (10) - это строка Unicode фиксированной длины длиной 10. nvarchar (10) - строка Unicode переменной длины с максимальной длиной 10. Как правило, вы должны использовать первую строку, если все значения данных составляют 10 символов, а последнюю. если длина различается.

Неправильное сравнение - вопрос касается nchar и varchar, а не nchar и nvarchar.

Luke Bennett 07.10.2008 02:56

NVARCHAR может хранить символы Unicode и занимает 2 байта на символ.

НЕПРАВИЛЬНЫЙ! Unicode использует от 1 до 4 байтов на символ! Многие об этом забывают! Даже использование UTF-16 может привести к тому, что некоторые символы будут занимать 4 байта вместо 2, хотя общая длина будет 2 байта. Некоторые другие подформаты Unicode могут занимать даже более 4 байтов!

Wim ten Brink 02.11.2009 13:37

@WimtenBrink - вопрос в SQL Server, а nvarchar всегда занимает 2 байта на символ.

Martin Smith 24.11.2011 03:15

@Wim, вы правы, есть несколько кодировок Unicode, которые могут выдавать разное количество байтов. Но SQL Server не дает вам выбора в отношении кодировки Unicode. В SQL Server до 2012 года использовался только UCS-2 шириной два байта, поэтому Мартин был прав, когда писал ответ. Как уже говорилось в других ответах выше, SQL Server 2012 теперь предоставляет UTF-16, поэтому два байта для многих символов (те, которые находятся в базовой многоязычной плоскости Unicode), четыре байта для других.

Concrete Gannet 07.02.2014 04:55
  • nchar имеет фиксированную длину и может содержать символы Юникода. он использует два байта памяти для каждого символа.

  • varchar имеет переменную длину и не может содержать символы Юникода. для каждого символа используется один байт памяти.

Неправильный. Юникод может использовать от 1 до 4 байтов (как правило) для каждого символа. Кроме того, varchar может содержать юникод, но он не распознается как юникод. В результате varchar считается ненадежным для хранения в Юникоде. (Тем более, что есть риск, что код, обращающийся к полю, переведет его неправильно.)

Wim ten Brink 02.11.2009 13:39

@Alex: Я думаю, вы высказали свою точку зрения, но я все еще не согласен с вами. Вы говорите, что int МОЖЕТ содержать long, если long оказывается меньше 2 ^ 32. Это не только «ненадежно», это внутреннее ограничение, которое делает невозможным охват всего диапазона значений.

Manu 05.11.2009 11:36

@ Мастерская Алекс: Неправильно. Юникод, закодированный как UCS-2 (который является кодировкой, используемой SQL Server), хранит каждый символ в двух байтах точно, см. msdn.microsoft.com/en-us/library/bb330962%28v=sql.90%29.aspx‌: SQL Server stores Unicode in the UCS-2 encoding scheme... UCS-2 is a fixed-length encoding that represents all characters as a 16-bit value (2 bytes). SQL Server 2008 может использовать сжатие SCSU, но по-прежнему используется сжатие строк Unicode в кодировке UCS-2: msdn.microsoft.com/en-us/library/ee240835.aspx

Remus Rusanu 18.12.2010 09:23
Ответ принят как подходящий

Просто чтобы прояснить ... или подвести итог ...

  • nchar и nvarchar могут хранить символы Юникод.
  • Символы char и varcharне может хранить Unicode.
  • char и nchar - это фиксированная длина, который будет зарезервировать место для хранения для количества символов, которое вы укажете, даже если вы не используете все это пространство.
  • varchar и nvarchar - это переменная длина, которые будут использовать пробелы только для хранимых вами символов. Это не резервирует хранилище, например char или nchar.

nchar и nvarchar будут занимать вдвое больше места для хранения, поэтому может быть разумно использовать их только в том случае, если вам нужна поддержка Юникод.

char и varchar не предназначены для хранения Unicode, но с некоторыми дополнительными приемами кодирования и дополнительной логикой вы все равно можете неправильно использовать поле [var] char для хранения Unicode.

Wim ten Brink 02.11.2009 13:41

Это зависит от того, занимают ли версии n... вдвое больше места для хранения как показывает мой ответ.

Martin Smith 24.11.2011 03:48

В чем преимущество резервирования хранилища?

mlissner 20.02.2013 04:11

По последнему пункту: использование Unicode nchar и nvarchar в большинстве случаев по-прежнему лучше, лучшая сортировка, гибкость для пользователей, устраняет будущие проблемы совместимости. И, кстати, место для хранения не является проблемой в этом случае, так как использование сортировки без Unicode доставляет много хлопот, и скорость памяти будет продолжать уменьшаться в будущем.

Jaison Varghese 25.05.2013 01:05

На самом деле ни char / varchar, ни nchar / nvarchar не могут хранить полный диапазон символов Unicode, поэтому неверно говорить, что один может хранить символы Unicode, а другой - нет. Фиксированная двухбайтовая кодировка на символ (SQL Server использует такую ​​кодировку, называемую UCS-2 для nchar и nvarchar) недостаточно велика, чтобы покрыть весь диапазон Unicode. См. Мой ответ для более подробной информации.

PeterAllenWebb 27.06.2013 09:57

Однако для [n] varchar вы можете хранить строки фиксированной длины, если хотите, например varchar (20). В чем разница между char (20) и varchar (20)?

Ben Caine 20.06.2014 19:00

@BenCaine char (20) будет использовать 20 байтов (при условии 8-битной сортировки); varchar (20) будет использовать len (data) +2 байта, то есть 22 для 20 байтов данных, но только 12 для 10 байтов данных. Дополнительные два байта - это записи о длине. Если ваши данные всегда будут полной длины, используйте char, так как это экономит место и может быть быстрее. Пожалуйста, никогда не используйте varchar (1) или что-то меньшее, чем varchar (4). Один символ в формате varchar использует три байта, поэтому char (3) никогда не будет занимать больше места, чем varchar (3).

Richard Gadsden 03.07.2014 19:31

@RichardGadsden Разве пустая строка varchar (3) не занимает меньше места, чем пустая строка char (3)? 2 байта против 3 байта?

andrewb 23.09.2014 06:29

@andrewb технически, но чаще у вас будет ноль, который в любом случае не является байтами.

Richard Gadsden 23.09.2014 11:14

Единственный другой случай, который я хотел бы здесь сделать, это то, что при попытке перенести данные из программы (например, веб-API asp.net) на SQL-сервер, и у вас есть столбец, установленный для char, он позволит вам обновить или вставить любой текущий тип в него. Это неверно или все еще можно сказать, приведите строку к char. Примером может служить поле StateAbbrv char (2) на сервере и public string StateAbbrv {get;set;} в приложении.

Edward 22.03.2017 05:39

nchar требует больше места чем nvarchar.

например,

Nchar (100) всегда будет хранить 100 символов, даже если вы введете только 5, оставшиеся 95 символов будут дополнены пробелами. Сохранение 5 символов в nvarchar (100) сэкономит 5 символов.

Не совсем так, поскольку вам необходимо заполнить char (100) до 100 символов. Вы можете использовать это, когда, например, храните телефонные номера в своей базе данных или номера заказов фиксированной длины. Поскольку длина поля фиксированная, у вас нет выбора, чтобы заполнить его до максимального количества символов. Но когда все ваши данные составляют 100 символов на запись, char (100) будет занимать меньше места, чем varchar (100), потому что ему не требуется указание длины: каждое значение будет ровно 100 символов.

Wim ten Brink 02.11.2009 13:44
  • char: символьные данные фиксированной длины с максимальной длиной 8000 символов.
  • nchar: данные Unicode фиксированной длины с максимальной длиной 4000 символов.
  • Char = длина 8 бит
  • NChar = длина 16 бит

char не может иметь длину 8 бит. Он не должен хранить длину, и фиксированная длина может составлять до 8000 символов.

John B. Lambe 16.07.2019 13:36

Различия - это:

  1. n [var] char хранит Unicode, а [var] char хранит только однобайтовые символы.
  2. [n] char требует фиксированного количества символов точной длины, в то время как [n] varchar принимает переменное количество символов до определенной длины включительно.

Еще одно отличие - длина. И nchar, и nvarchar могут иметь длину до 4000 символов. И char и varchar могут быть длиной до 8000 символов. Но для SQL Server вы также можете использовать [n] varchar (max), который может обрабатывать до 2 147 483 648 символов. (Два гигабайта, 4-байтовое целое число со знаком.)

Просто чтобы добавить еще: нчар - добавляет конечные пробелы к данным. nvarchar - не добавляет конечные пробелы к данным.

Итак, если вы собираетесь фильтровать свой набор данных по полю nchar, вы можете использовать RTRIM для удаления пробелов. Например. В поле nchar (10) с именем BRAND хранится слово NIKE. Он добавляет 6 пробелов справа от слова. Итак, при фильтрации выражение должно читать: RTRIM (Fields! BRAND.Value) = "NIKE"

Надеюсь, это поможет кому-то там, потому что я только что немного боролся с этим!

каждая опция добавляет конечное пространство в моем SQL Server ...: /

Gustavo Contreiras 01.09.2020 19:33

Все ответы на данный момент указывают, что varchar - однобайтный, nvarchar - двухбайтный. Первая часть этого на самом деле зависит от сопоставления, как показано ниже.

DECLARE @T TABLE
(
C1 VARCHAR(20) COLLATE Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS,
C2 NVARCHAR(20)COLLATE  Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS
)

INSERT INTO @T 
    VALUES (N'中华人民共和国',N'中华人民共和国'),
           (N'abc',N'abc');

SELECT C1,
       C2,
       LEN(C1)        AS [LEN(C1)],
       DATALENGTH(C1) AS [DATALENGTH(C1)],
       LEN(C2)        AS [LEN(C2)],
       DATALENGTH(C2) AS [DATALENGTH(C2)]
FROM   @T  

Возврат

Обратите внимание, что символы и все еще не были представлены в версии VARCHAR и были незаметно заменены на ?.

На самом деле все еще нет китайских иероглифов, которые можно было бы представить одним байтом в этом сопоставлении. Единственные однобайтовые символы - это типичный западный набор ASCII.

Из-за этого возможна вставка из столбца nvarchar(X) в столбец varchar(X)выйти из строя с ошибкой усечения (где X обозначает число, одинаковое в обоих случаях).

SQL Server 2012 добавляет параметры сортировки SC (дополнительные символы), которые поддерживают UTF-16. В этих сопоставлениях один символ nvarchar может занимать 2 или 4 байта.

Ответ, который я искал. Также, чтобы сэкономить время для таких, как я - неанглийский текст переводится как «Китайская Народная Республика» translate.google.com/#auto/en/…

Igand 14.03.2018 16:17

Моя попытка обобщить и исправить существующие ответы:

Во-первых, char и nchar всегда будут использовать фиксированный объем дискового пространства, даже если строка, которую нужно сохранить, меньше доступного пространства, тогда как varchar и nvarchar будут использовать только столько дискового пространства, сколько необходимо для хранения этой строки (плюс два байтов накладных расходов, предположительно для хранения длины строки). Так что помните, что «var» означает «переменная», как в пространстве переменных.

Второй важный момент, который следует понять, заключается в том, что nchar и nvarchar хранят строки с использованием точно по два байта на символ, тогда как char и varchar используют кодировку, определяемую кодовой страницей сопоставления, которая будет как правило ровно одним байтом на символ (хотя есть исключения, см. ниже). Используя два байта на символ, можно сохранить очень широкий диапазон символов, поэтому важно помнить, что nchar и nvarchar, как правило, являются гораздо лучшим выбором, когда вам нужна поддержка интернационализации, что вы, вероятно, и делаете.

Теперь о некоторых тонкостях.

Во-первых, столбцы всегдаnchar и nvarchar хранят данные с использованием UCS-2. Это означает, что будет использоваться ровно два байта на символ, и любой символ Unicode в базовой многоязычной плоскости (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.

nchar[(n)] (национальный символ)

  • Строковые данные фиксированной длины Юникод.
  • n определяет длину строки и должен иметь значение от 1 до 4000.
  • Размер хранилища в два раза больше n байт.

nvarchar [(n | max)] (национальные символы меняются.)

  • Строковые данные переменной длины Юникод.
  • n определяет длину строки и может принимать значения от 1 до 4000.
  • max указывает, что максимальный размер хранилища составляет 2 ^ 31-1 байта (2 ГБ).
  • Размер хранилища в байтах в два раза превышает фактическую длину введенных данных + 2 байта.

char [(n)] (персонаж)

  • Строковые данные non-Unicode фиксированной длины.
  • n определяет длину строки и должен иметь значение от 1 до 8000.
  • Размер хранилища составляет n байт.

varchar [(n | max)] (изменение символа)

  • Строковые данные переменной длины, не-Юникод.
  • n определяет длину строки и может принимать значения от 1 до 8000.
  • max указывает, что максимальный размер хранилища составляет 2 ^ 31-1 байта (2 ГБ).
  • Размер хранилища - это фактическая длина введенных данных + 2 байта.

Другие вопросы по теме