Jaka jest różnica między char, nchar, varchar i nvarchar w SQL Server?


Odpowiedzi:


856

Aby wyjaśnić ... lub podsumować ...

  • nchari nvarcharmoże przechowywać znaki Unicode .
  • chari nie może przechowywać znaków Unicode .varchar
  • chari ncharmają stałą długość, która zarezerwuje miejsce do przechowywania określonej liczby znaków, nawet jeśli nie wykorzystasz całej tej przestrzeni.
  • varchari nvarcharmają zmienną długość, która zużyje spacje tylko dla przechowywanych znaków. Nie rezerwuje miejsca takiego jak charlubnchar .

nchari nvarcharzajmie dwa razy więcej miejsca do przechowywania, więc rozsądne może być użycie ich tylko wtedy, gdy potrzebujesz obsługi Unicode .


15
char i varchar nie są przeznaczone do przechowywania kodu Unicode, ale dzięki dodatkowym sztuczkom kodującym i dodatkowej logice nadal można nieprawidłowo wykorzystywać pole [var] char do przechowywania w Unicode.
Wim ten Brink

10
Zależy to od sortowania, czy n...wersje zajmują dwa razy więcej miejsca do przechowywania, niż pokazuje moja odpowiedź
Martin Smith,

7
Jaka jest zaleta rezerwowania pamięci?
mlissner

4
W ostatnim punkcie: korzystanie z Unicode nchar i nvarchar jest nadal lepsze w większości przypadków, lepsze zestawianie, elastyczność dla użytkowników, usuwa przyszłe problemy ze zgodnością. Nawiasem mówiąc, przestrzeń dyskowa nie jest problemem w tym przypadku, ponieważ korzystanie z sortowania bez Unicode jest bardzo kłopotliwe, a szybkość pamięci będzie nadal spadać w przyszłości
Jaison Varghese

6
@BenCaine char (20) użyje 20 bajtów (przy założeniu 8-bitowego sortowania); varchar (20) użyje len (dane) + 2 bajty, tj. 22 na 20 bajtów danych, ale tylko 12 na 10 bajtów danych. Dodatkowe dwa bajty to rekordy długości. Jeśli Twoje dane będą zawsze pełnej długości, użyj znaku, ponieważ oszczędza miejsce i może być szybsze. Proszę nigdy nie używać varchar (1), a nawet czegoś mniejszego niż varchar (4). Pojedynczy znak w formacie varchar używa trzech bajtów, więc char (3) nigdy nie zajmie więcej miejsca niż varchar (3).
Richard Gadsden

95

Wszystkie dotychczasowe odpowiedzi wskazują, że varcharjest to jeden bajt, nvarchar jest dwubajtowy. Pierwsza część tego zależy od sortowania, jak pokazano poniżej.

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  

Zwroty

wprowadź opis zdjęcia tutaj

Zauważ, że znaki i nadal nie były reprezentowane w VARCHARwersji i zostały po cichu zastąpione przez? .

W rzeczywistości nadal nie ma chińskich znaków, które mogą być reprezentowane przez jeden bajt w tym zestawieniu. Jedynymi jednobajtowymi znakami są typowe zachodnie zestawy ASCII.

Z tego powodu możliwe jest, że wstawianie z nvarchar(X)kolumny do varchar(X)kolumny nie powiedzie się z powodu błędu obcięcia (gdzie X oznacza liczbę, która jest taka sama w obu przypadkach).

SQL Server 2012 dodaje obsługiwane przez SC sortowania znaków uzupełniających UTF-16. W tych zestawieniach pojedynczy nvarcharznak może zająć 2 lub 4 bajty.


4
Tego rodzaju odpowiedzi szukałem. Również, aby zaoszczędzić czas na takich jak ja - nie-angielski tekst przekłada się na „Republiki Ludowej” translate.google.com/#auto/en/...
Igand

34

nchar i char działają prawie tak samo jak nawzajem, podobnie jak nvarchar i varchar. Jedyna różnica między nimi polega na tym, że nchar / nvarchar przechowuje znaki Unicode (niezbędne, jeśli wymagane jest użycie rozszerzonych zestawów znaków), podczas gdy varchar tego nie robi.

Ponieważ znaki Unicode wymagają więcej pamięci, pola nchar / nvarchar zajmują dwa razy więcej miejsca (więc na przykład we wcześniejszych wersjach SQL Server maksymalny rozmiar pola nvarchar wynosi 4000).

To pytanie jest duplikatem tego .


3
Zapominasz jednej rzeczy: nchar używa stałej długości, więc nchar (10) zawsze musi otrzymać dziesięć znaków. A varchar (10) jest rzeczywiście Unicode i akceptuje dowolną liczbę znaków, do 10 znaków. Zobacz także msdn.microsoft.com/en-us/library/ms186939.aspx
Wim ten Brink

33

Aby dodać coś jeszcze: nchar - dodaje końcowe spacje do danych. nvarchar - nie dodaje końcowych spacji do danych.

Tak więc, jeśli zamierzasz przefiltrować zestaw danych według pola „nchar”, możesz użyć RTRIM do usunięcia spacji. Np. Pole nchar (10) o nazwie BRAND przechowuje słowo NIKE. Dodaje 6 spacji po prawej stronie słowa. Tak więc podczas filtrowania wyrażenie powinno brzmieć: RTRIM (Fields! BRAND.Value) = "NIKE"

Mam nadzieję, że to pomaga komuś tam, bo właśnie przez chwilę z tym walczyłem!


24

Moja próba streszczenia i poprawienia istniejących odpowiedzi:

Po pierwsze chari ncharzawsze będzie używać stałej ilości miejsca do przechowywania, nawet jeśli ciąg do przechowywania jest mniejszy niż dostępne miejsce, varchara jednocześnie nvarcharzużyje tylko tyle miejsca, ile jest potrzebne do przechowywania tego ciągu (plus dwa bajty narzutu, przypuszczalnie do przechowywania długości łańcucha). Pamiętaj więc, że „var” oznacza „zmienną”, podobnie jak w przestrzeni zmiennej.

Drugim ważnym punktem do zrozumienia jest to, że nchari nvarcharprzechowujemy ciągi znaków, używając dokładnie dwóch bajtów na znak, chara także varcharużywamy kodowania określonego przez stronę kodową sortowania, który zwykle będzie dokładnie jednym bajtem na znak (chociaż są wyjątki, patrz poniżej). Używając dwóch bajtów na znak, można przechowywać bardzo szeroki zakres znaków, więc podstawową rzeczą do zapamiętania tutaj jest to nchari nvarcharzwykle jest on znacznie lepszym wyborem, gdy potrzebujesz obsługi internacjonalizacji, co prawdopodobnie robisz.

Teraz kilka drobniejszych punktów.

Po pierwsze, nchari nvarcharkolumny zawsze przechowywać dane przy użyciu UCS-2. Oznacza to, że zostaną użyte dokładnie dwa bajty na znak, a dowolny znak Unicode w Basic Multilingual Plane (BMP) może być przechowywany przez pole ncharlub nvarchar. Jednak nie jest tak, że można zapisać dowolny znak Unicode. Na przykład według Wikipedii punkty kodowe egipskich hieroglifów nie mieszczą się w zakresie BMP. Istnieją zatem ciągi znaków Unicode, które mogą być reprezentowane w UTF-8, i inne prawdziwe kodowania Unicode, których nie można przechowywać w SQL Server ncharlub nvarcharpolu, a wśród nich byłyby ciągi napisane w egipskich hieroglifach. Na szczęście użytkownicy prawdopodobnie nie piszą w tym skrypcie, ale warto o tym pamiętać!

Innym interesującym punktem jednak mylące, że inne plakaty podkreśliły, że chari varcharpola mogą korzystać z dwóch bajtów na znak dla pewnych znaków czy strona kodowa sortowania wymaga. (Martin Smith podaje doskonały przykład, w którym pokazuje, jak Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS wykazuje to zachowanie. Sprawdź to.)

AKTUALIZACJA: Począwszy od SQL Server 2012, są wreszcie strony kodowe dla UTF-16 , na przykład Latin1_General_100_CI_AS_SC, które mogą naprawdę obejmować cały zakres Unicode.


14
  • char: dane o stałej długości o maksymalnej długości 8000 znaków.
  • nchar: dane Unicode o stałej długości i maksymalnej długości 4000 znaków.
  • Char = 8 bitów długości
  • NChar = 16 bitów długości

charnie może mieć długości 8 bitów. Nie musi przechowywać długości, a stała długość może wynosić do 8000 znaków.
John B. Lambe,

12

nchar[(n)] (charakter narodowy)

  • Dane o ciągach znaków Unicode o stałej długości .
  • n określa długość łańcucha i musi mieć wartość od 1 do 4 000.
  • Rozmiar pamięci to dwa razy nbajty.

nvarchar [(n | max)] (charakter narodowy różni się.)

  • Dane łańcuchowe Unicode o zmiennej długości .
  • n określa długość łańcucha i może mieć wartość od 1 do 4 000.
  • max wskazuje, że maksymalny rozmiar pamięci to 2 ^ 31-1 bajtów (2 GB).
  • Rozmiar pamięci, w bajtach, jest dwa razy większy niż rzeczywista długość wprowadzonych danych + 2 bajty

char [(n)] (postać)

  • non-UnicodeDane łańcuchowe o stałej długości .
  • n określa długość łańcucha i musi mieć wartość od 1 do 8 000.
  • Rozmiar pamięci to nbajty.

varchar [(n | max)] (różni się charakter)

  • Dane łańcuchowe o zmiennej długości, inne niż Unicode .
  • n określa długość łańcucha i może mieć wartość od 1 do 8 000.
  • max wskazuje, że maksymalny rozmiar pamięci to 2 ^ 31-1 bajtów (2 GB).
  • Rozmiar pamięci to faktyczna długość wprowadzonych danych + 2 bajty.

7

Różnice są następujące:

  1. n [var] char przechowuje Unicode, podczas gdy [var] char tylko przechowuje znaki jednobajtowe.
  2. [n] char wymaga stałej liczby znaków o dokładnej długości, podczas gdy [n] varchar akceptuje zmienną liczbę znaków do zdefiniowanej długości włącznie.

Kolejną różnicą jest długość. Zarówno nchar, jak i nvarchar mogą mieć do 4000 znaków. A char i varchar mogą mieć do 8000 znaków. Ale w przypadku SQL Server można również użyć [n] varchar (max), który może obsłużyć do 2 147 483 648 znaków. (Dwa gigabajty, 4-bajtowa liczba całkowita ze znakiem).


7

nchar wymaga więcej miejsca niż nvarchar.

na przykład,

Nchar (100) zawsze będzie przechowywać 100 znaków, nawet jeśli wpiszesz tylko 5, pozostałe 95 znaków zostanie wypełnionych spacjami. Przechowywanie 5 znaków w nvarchar (100) spowoduje zapisanie 5 znaków.


6
Nie do końca prawda, ponieważ musisz wypełnić znak (100) maksymalnie 100 znakami. Używałbyś tego, gdy np. Przechowujesz numery telefonów w bazie danych lub zamawiasz numery o stałej długości. Ponieważ długość pola jest stała, nie ma możliwości wypełnienia go do maksymalnej liczby znaków. Ale gdy wszystkie twoje dane mają 100 znaków na rekord, char (100) zajmie mniej miejsca niż varchar (100), ponieważ nie potrzebuje oznaczenia długości: każda wartość będzie dokładnie 100 znaków.
Wim ten Brink

5

nchar (10) to ciąg Unicode o stałej długości o długości 10. nvarchar (10) to ciąg Unicode o zmiennej długości o maksymalnej długości 10. Zwykle użyłbyś tego pierwszego, gdyby wszystkie wartości danych miały 10 znaków, a drugiego jeśli długości się różnią.


Błędne porównanie - pytanie dotyczy nchar i varchar, a nie nchar i nvarchar.
Luke Bennett,

4
  • nchar ma stałą długość i może przechowywać znaki Unicode. wykorzystuje dwa bajty pamięci na znak.

  • varchar ma zmienną długość i nie może przechowywać znaków Unicode. używa jednego bajtu pamięci na znak.


Źle. Unicode może używać od 1 do 4 bajtów (ogólnie) dla każdego znaku. Ponadto varchar może przechowywać Unicode, ale nie jest rozpoznawany jako Unicode. W rezultacie varchar jest uważany za niewiarygodny w przypadku przechowywania w trybie Unicode. (Zwłaszcza, że ​​istnieje ryzyko, że kod uzyskujący dostęp do pola przetłumaczy go niepoprawnie.)
Wim ten Brink

@Alex: Myślę, że masz rację, ale nadal się z tobą nie zgadzam. To, co mówisz, to to, że int MOŻE trzymać długo, jeśli zdarzy się, że jest mniejsze niż 2 ^ 32. Jest to nie tylko „niewiarygodne”, ale jest nieodłącznym ograniczeniem, które uniemożliwia objęcie całego zakresu wartości.
Manu,

4
@ Workshop Alex: Źle. Zakodowane jako Unicode UCS-2(co zdarza się kodowanie używane przez SQL Server) przechowuje każdy znak w dokładnie dwa bajty, zobacz 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 może korzystać z kompresji SCSU, ale nadal jest kompresją ciągów znaków Unicode zakodowanych w UCS-2: msdn.microsoft.com/en-us/library/ee240835.aspx
Remus Rusanu

2

NVARCHAR może przechowywać znaki Unicode i zajmuje 2 bajty na znak.


1
ŹLE! Unicode wykorzystuje od 1 do 4 bajtów na znak! Wiele osób zapomina o tym! Nawet użycie UTF-16 może spowodować, że niektóre znaki zajmą 4 bajty zamiast 2, chociaż wspólna długość to 2 bajty. Niektóre inne podformaty Unicode mogą zająć nawet więcej niż 4 bajty!
Wim ten Brink

7
@WimtenBrink - Pytanie dotyczy programu SQL Server i nvarcharzawsze zajmuje 2 bajty na znak.
Martin Smith

@ Wim, masz rację, istnieje kilka kodowań Unicode, które mogą generować inną liczbę bajtów. Ale SQL Server nie daje możliwości wyboru kodowania Unicode. SQL Server przed 2012 r. Używał tylko UCS-2 o szerokości dwóch bajtów, więc Martin miał rację w momencie, gdy napisał odpowiedź. Jak już powiedziano w innych odpowiedziach, SQL Server 2012 zapewnia teraz UTF-16, więc dwa bajty dla wielu znaków (te w wielojęzycznym podstawowym języku Unicode), cztery bajty dla innych.
Beton Głuptak
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.