Яка різниця між char, nchar, varchar і nvarchar у SQL Server?


Відповіді:


856

Просто, щоб очистити ... або підбити підсумки ...

  • ncharі nvarcharможе зберігати символи Unicode .
  • charі не може зберігати символи Unicode .varchar
  • charі ncharмають фіксовану довжину, що дозволить зберегти місце для зберігання для кількості вказаних вами символів, навіть якщо ви не використовуєте весь цей простір.
  • varcharі nvarcharмають змінну довжину, яка використовуватиме пробіли лише для символів, які ви зберігаєте. Він не зарезервує сховище типу charабоnchar .

ncharі nvarcharзайме вдвічі більше місця для зберігання, тому може бути розумним використовувати їх, лише якщо вам потрібна підтримка Unicode .


15
char та varchar не призначені для зберігання unicode, але, використовуючи додаткові хитрості кодування та додаткову логіку, ви все одно можете неправильно використовувати поле [var] char для зберігання унікоду.
Wim ten Brink

10
Це залежить від того, чи n...займають версії вдвічі більше місця для зберігання, ніж показує моя відповідь
Martin Smith

7
У чому перевага резервування сховища?
mlissner

4
Останнє питання: Використання Unicode nchar та nvarchar все ще краще в більшості випадків, краща взаємодія, гнучкість для користувачів, усуває майбутні проблеми сумісності. І, до речі, простір пам’яті не є проблемою для цього випадку, оскільки використання зіставлення без Unicode - це багато клопоту, а швидкість пам’яті надалі знизиться
Jaison Varghese,

6
@BenCaine char (20) буде використовувати 20 байт (припускаючи 8-бітове зіставлення); varchar (20) використовуватиме len (data) +2 байти, тобто 22 для 20 байт даних, але лише 12 для 10 байт даних. Додаткові два байти - це записи довжини. Якщо ваші дані завжди будуть на повну довжину, використовуйте табличку, оскільки це економить місце і може бути швидше. Будь ласка, не використовуйте ніколи варчар (1), ані щось менше, ніж варчар (4). Один символ у форматі varchar використовує три байти, тому char (3) ніколи не буде використовувати більше місця, ніж varchar (3).
Річард Ґадсден

95

Усі відповіді поки що вказують, що 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 байти.


4
Таку відповідь я шукав. Крім того, щоб заощадити час, який подобається мені - текст, який не є англійською, перекладається на "Китайська Народна Республіка" translate.google.com/#auto/en/…
Іганд,

34

nchar та char в значній мірі діють точно так само, як один одного, як і nvarchar та varchar. Єдина відмінність між ними полягає в тому, що nchar / nvarchar зберігає символи Unicode (важливо, якщо потрібно використовувати розширені набори символів), тоді як varchar цього не робить.

Оскільки символам Unicode потрібно більше пам’яті, поля nchar / nvarchar займають вдвічі більше місця (наприклад, у попередніх версіях SQL Server максимальний розмір поля nvarchar - 4000).

Це питання є дублікатом цього .


3
Ви забуваєте одне: nchar використовує фіксовану довжину, тому nchar (10) завжди повинен отримувати десять символів. І varchar (10) справді є Unicode і може приймати будь-яку кількість символів, до 10 символів. Також дивіться msdn.microsoft.com/en-us/library/ms186939.aspx
Wim ten Brink

33

Просто додати щось більше: nchar - додає проміжні проміжки до даних. nvarchar - не додає проміжки проміжків до даних.

Отже, якщо ви збираєтеся фільтрувати ваш набір даних за полем 'nchar', ви можете скористатися RTRIM для видалення пробілів. Наприклад, поле nchar (10) під назвою БРЕНД зберігає слово NIKE. Він додає 6 пробілів праворуч від слова. Отже, під час фільтрації вираз повинен читати: RTRIM (Поля! BRAND.Value) = "NIKE"

Сподіваюся, це допомагає комусь там, тому що я трохи боровся з цим!


24

Моя спроба узагальнити та виправити існуючі відповіді:

По-перше, charі ncharзавжди використовуватиме фіксовану кількість місця для зберігання, навіть коли рядок, який потрібно зберігати, менший, ніж наявний простір, тоді як varcharі nvarcharбуде використовувати лише стільки місця, скільки потрібно для зберігання цього рядка (плюс два байти накладних витрат, імовірно, щоб зберегти довжину рядка). Тому пам’ятайте, що "var" означає "змінну", як у змінному просторі.

Другий головний момент, який потрібно зрозуміти, полягає в тому, що ncharі nvarcharзберігайте рядки, використовуючи рівно два байти на символ, тоді як charі varcharвикористовуйте кодування, визначене кодовою сторінкою зіставлення, яка зазвичай буде рівно одним байтом на символ (хоча є винятки, див. Нижче). Використовуючи два байти на персонаж, можна зберігати дуже широкий діапазон символів, тому основне, що слід пам’ятати тут, - це ncharі, nvarcharяк правило, є набагато кращим вибором, коли ви хочете підтримати інтернаціоналізацію, що ви, мабуть, робите.

Тепер ще кілька тонких моментів.

По- перше, ncharі nvarcharстовпці завжди зберігати дані з використанням UCS-2. Це означає, що буде використано рівно два байти на символ, а будь-який символ Unicode в базовій багатомовній площині (BMP) може бути збережений у полі ncharабо в nvarcharполі. Однак це не так, що будь-який символ Unicode може бути збережений. Наприклад, згідно з Вікіпедією, кодові точки для єгипетських ієрогліфів виходять за межі БМП. Тому існують рядки Unicode, які можуть бути представлені в UTF-8 та інші справжні кодування Unicode, які не можуть бути збережені на SQL сервері ncharчи nvarcharполі, а рядки, написані в єгипетських ієрогліфах, були б серед них. На щастя, ваші користувачі, ймовірно, не пишуть у цьому сценарії, але це потрібно пам’ятати!

Інший заплутаний , але цікавий момент , що інші плакати висвітили, що charі varcharполя можуть використовувати два байт на символ для певних символів , якщо сторінка сортування коду вимагає. (Мартін Сміт наводить чудовий приклад, в якому він показує, як китайська_традиційна_Строке_Ордер_100_CS_AS_KS_WS проявляє цю поведінку. Перевірте це.)

ОНОВЛЕННЯ: Станом на SQL Server 2012, нарешті, існують кодові сторінки для UTF-16 , наприклад Latin1_General_100_CI_AS_SC, які можуть справді охопити весь діапазон Unicode.


14
  • char: дані символів фіксованої довжини з максимальною довжиною 8000 символів.
  • nchar: дані Unicode фіксованої довжини з максимальною довжиною 4000 символів.
  • Char = 8 бітова довжина
  • NChar = 16 бітова довжина

charне могла мати 8-бітну довжину. Він не повинен зберігати довжину, і фіксована довжина може становити до 8000 символів.
Джон Б. Ламбе

12

nchar[(n)] (національний характер)

  • Дані рядка Unicode з фіксованою довжиною .
  • n визначає довжину рядка і має бути значенням від 1 до 4000.
  • Розмір пам’яті - два рази n.

nvarchar [(n | max)] (національний характер змінюється.)

  • Дані рядка Unicode змінної довжини .
  • n визначає довжину рядка і може бути значенням від 1 до 4000.
  • max вказує, що максимальний розмір пам’яті становить 2 ^ 31-1 байт (2 ГБ).
  • Розмір пам’яті в байтах вдвічі перевищує фактичну довжину введених даних + 2 байти

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

  • non-UnicodeДані рядка з фіксованою довжиною .
  • n визначає довжину рядка і має бути значенням від 1 до 8000.
  • Розмір пам’яті - nбайти.

varchar [(n | max)] (характер змінюється)

  • Дані про рядки Unicode змінної довжини .
  • n визначає довжину рядка і може бути значенням від 1 до 8000.
  • max вказує, що максимальний розмір пам’яті становить 2 ^ 31-1 байт (2 ГБ).
  • Розмір пам’яті - це фактична довжина введених даних + 2 байти.

7

Відмінності :

  1. n [var] char зберігає unicode, тоді як [var] char просто зберігає однобайтові символи.
  2. [n] char вимагає фіксовану кількість символів точної довжини, тоді як [n] varchar приймає змінну кількість символів до включеної визначеної довжини.

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


7

nchar вимагає більше місця, ніж nvarchar.

наприклад,

Nchar (100) завжди буде зберігати 100 символів, навіть якщо ви введете лише 5, решта 95 символів будуть пробілами. Збереження 5 символів в nvarchar (100) дозволить зберегти 5 символів.


6
Не зовсім правда, оскільки вам потрібно заповнити знак (100) до 100 символів. Ви б використовували це, коли ви, наприклад, зберігаєте номери телефонів у вашій базі даних або замовляєте номери з фіксованою довжиною. Оскільки довжина поля фіксована, у вас немає вибору заповнити її до максимальної кількості символів. Але коли всі ваші дані становлять 100 символів на запис, знак char (100) займе менше місця, ніж варчар (100), тому що він не потребує вказівки довжини: кожне значення буде рівно 100 символів.
Wim ten Brink

5

nchar (10) - рядок Unicode фіксованої довжини 10. nvarchar (10) - рядок Unicode змінної довжини з максимальною довжиною 10. Як правило, ви використовуєте перший, якщо всі значення даних становлять 10 символів, а останній якщо довжини різні.


Неправильне порівняння - питання стосується nchar та varchar, а не nchar та nvarchar.
Люк Беннетт

4
  • nchar має фіксовану довжину і може містити символи unicode. він використовує два байти зберігання на символ.

  • varchar має різну довжину і не може містити символи unicode. він використовує один байт сховища на символ.


Неправильно. Unicode може використовувати від 1 до 4 байтів (загалом) для кожного символу. Також varchar може містити unicode, але він не розпізнається як unicode. Як результат, варчар вважається ненадійним для зберігання унікоду. (Тим більше, що існує ризик, що код, який звертається до поля, перекладе його неправильно.)
Wim ten Brink

@ Алекс: Я думаю, ви зробили свою думку, але я все ще не згоден з вами. Що ви говорите, це те, що int CAN може тримати довгий, якщо довгий виявляється меншим за 2 ^ 32. Це не лише "ненадійне", це властиве обмеження, яке унеможливлює охоплення всього діапазону значень.
Ману

4
@Workshop Alex: Неправильно. Unicode закодований як 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
Remus Rusanu

2

NVARCHAR може зберігати символи Unicode і займає 2 байти на символ.


1
НЕ ПРАВО! Unicode використовує від 1 до 4 байт на символ! Багато людей це забувають! Навіть використання UTF-16 може призвести до того, що деякі символи візьмуть 4 байти замість 2, хоча загальна довжина буде 2 байти. Деякі інші підформати Unicode можуть займати навіть більше 4-х байт!
Wim ten Brink

7
@WimtenBrink - питання про SQL Server і nvarcharзавжди займає 2 байти на символ.
Мартін Сміт

@Wim, ви праві, є кілька кодувань для Unicode, які можуть створювати різну кількість байтів. Але SQL Server не дає вам вибору щодо кодування Unicode. До 2012 року SQL Server використовував лише UCS-2, шириною два байти, тому Мартін був правильним у той момент, коли він писав відповідь. Як було сказано в інших відповідях вище, тепер SQL Server 2012 надає UTF-16, тому два байти для багатьох символів (ті, які знаходяться в багатомовної площині Unicode Basic), чотири байти для інших.
Бетон Gannet
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.