Was ist der Unterschied zwischen char, nchar, varchar und nvarchar in SQL Server?

622

Was ist damit gemeint nvarchar?

Was ist der Unterschied zwischen char, nchar, varcharund nvarcharin SQL Server?

MrDatabase
quelle

Antworten:

856

Nur um aufzuklären ... oder zusammenzufassen ...

  • ncharund nvarcharkann Unicode- Zeichen speichern .
  • charund kann keine Unicode- Zeichen speichern .varchar
  • charund ncharhaben eine feste Länge, die Speicherplatz für die von Ihnen angegebene Anzahl von Zeichen reserviert , auch wenn Sie nicht den gesamten Speicherplatz belegen.
  • varcharund nvarcharhaben eine variable Länge, die nur Leerzeichen für die von Ihnen gespeicherten Zeichen verbraucht. Es wird kein Speicher wie charoder reserviertnchar .

ncharund nvarcharnimmt doppelt so viel Speicherplatz ein, daher ist es möglicherweise ratsam, sie nur zu verwenden, wenn Sie Unicode- Unterstützung benötigen .

Brian Kim
quelle
15
char und varchar sind nicht zum Speichern von Unicode gedacht, aber mit einigen zusätzlichen Codierungstricks und zusätzlicher Logik können Sie ein [var] char-Feld dennoch für die Unicode-Speicherung missbrauchen.
Wim ten Brink
10
Es hängt von der Sortierung ab, ob die n...Versionen doppelt so viel Speicherplatz
Martin Smith,
7
Was ist der Vorteil bei der Reservierung von Speicherplatz?
mlissner
4
Am letzten Punkt: Die Verwendung von Unicode nchar und nvarchar ist in den meisten Fällen immer noch besser. Eine bessere Sortierung, Flexibilität für die Benutzer und zukünftige Kompatibilitätsprobleme werden behoben. Übrigens ist Speicherplatz in diesem Fall kein Problem, da die Verwendung der Kollatierung ohne Unicode ein großer Aufwand ist und die Speicherraten in Zukunft weiter sinken werden
Jaison Varghese,
6
@BenCaine char (20) verwendet 20 Bytes (unter der Annahme einer 8-Bit-Kollatierung); varchar (20) verwendet len ​​(Daten) +2 Bytes, dh 22 für 20 Datenbytes, aber nur 12 für 10 Datenbytes. Die zusätzlichen zwei Bytes sind die Längenaufzeichnungen. Wenn Ihre Daten immer die volle Länge haben, verwenden Sie ein Zeichen, da dies Platz spart und möglicherweise schneller ist. Bitte verwenden Sie niemals einen Varchar (1) oder etwas kleineres als einen Varchar (4). Ein einzelnes Zeichen im Varchar-Format verwendet drei Bytes, sodass ein Zeichen (3) niemals mehr Speicherplatz als ein Varchar (3) benötigt.
Richard Gadsden
95

Alle bisherigen Antworten geben an, dass varchares sich bei einem Einzelbyte nvarchar um ein Doppelbyte handelt. Der erste Teil davon hängt tatsächlich von der Sortierung ab, wie unten dargestellt.

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  

Kehrt zurück

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass die Zeichen und in der VARCHARVersion immer noch nicht dargestellt wurden und stillschweigend durch ersetzt wurden ?.

Es gibt tatsächlich noch keine chinesischen Schriftzeichen, die durch ein einzelnes Byte in dieser Zusammenstellung dargestellt werden können. Die einzigen Einzelbytezeichen sind die typischen westlichen ASCII-Sätze.

Aus diesem Grund kann ein Einfügen von einer nvarchar(X)Spalte in eine varchar(X)Spalte mit einem Kürzungsfehler fehlschlagen (wobei X eine Zahl bezeichnet, die in beiden Fällen gleich ist).

SQL Server 2012 fügt unterstützende SC-Kollatierungen (Supplementary Character) hinzu UTF-16. In diesen Kollatierungen kann ein einzelnes nvarcharZeichen 2 oder 4 Bytes benötigen.

Martin Smith
quelle
4
Die Art von Antwort, nach der ich gesucht habe. Auch um Zeit für Leute wie mich zu sparen - der nicht-englische Text übersetzt in "Volksrepublik China" translate.google.com/#auto/en/…
Igand
34

nchar und char funktionieren genauso wie nvarchar und varchar. Der einzige Unterschied zwischen ihnen besteht darin, dass nchar / nvarchar Unicode-Zeichen speichert (wichtig, wenn Sie erweiterte Zeichensätze benötigen), während varchar dies nicht tut.

Da Unicode-Zeichen mehr Speicherplatz benötigen, belegen nchar / nvarchar-Felder doppelt so viel Speicherplatz (beispielsweise beträgt die maximale Größe eines nvarchar-Felds in früheren Versionen von SQL Server 4000).

Diese Frage ist ein Duplikat dieser Frage .

Luke Bennett
quelle
3
Sie vergessen eines: nchar verwendet eine feste Länge, sodass nchar (10) immer zehn Zeichen empfangen muss. Und varchar (10) ist in der Tat Unicode und akzeptiert eine beliebige Anzahl von Zeichen, bis zu 10 Zeichen. Siehe auch msdn.microsoft.com/en-us/library/ms186939.aspx
Wim ten Brink
33

Nur um noch etwas hinzuzufügen: nchar - fügt den Daten nachgestellte Leerzeichen hinzu. nvarchar - fügt den Daten keine nachgestellten Leerzeichen hinzu.

Wenn Sie also Ihr Dataset nach einem 'nchar'-Feld filtern möchten, können Sie die Leerzeichen mit RTRIM entfernen. Das Feld nchar (10) mit dem Namen BRAND speichert beispielsweise das Wort NIKE. Es werden 6 Leerzeichen rechts vom Wort hinzugefügt. Beim Filtern sollte der Ausdruck also lauten: RTRIM (Fields! BRAND.Value) = "NIKE"

Hoffe, das hilft jemandem da draußen, weil ich gerade ein bisschen damit zu kämpfen hatte!

Dimuthu
quelle
24

Mein Versuch, die vorhandenen Antworten zusammenzufassen und zu korrigieren:

Erstens charund verwendet ncharimmer eine feste Menge an Speicherplatz, selbst wenn die zu speichernde Zeichenfolge kleiner als der verfügbare Speicherplatz ist, während varcharund nvarcharnur so viel Speicherplatz verwendet wird, wie zum Speichern dieser Zeichenfolge erforderlich ist (plus zwei Byte Overhead). vermutlich um die Stringlänge zu speichern). Denken Sie also daran, "var" bedeutet "Variable", wie im variablen Raum.

Der zweite wichtige Punkt zu verstehen ist , dass, ncharund nvarcharSpeichern von Zeichenfolgen mit genau zwei Bytes pro Zeichen, während charund varchareine Codierung durch die Sortiercodepage bestimmt verwenden, das wird in der Regel genau ein Byte pro Zeichen sein (obwohl es Ausnahmen gibt, siehe unten). Durch die Verwendung von zwei Bytes pro Zeichen kann ein sehr breites Spektrum von Zeichen gespeichert werden, so dass hier die grundlegende Sache zu erinnern ist , dass ncharund nvarcharneigen dazu , eine viel bessere Wahl zu sein , wenn Sie Unterstützung der Internationalisierung mögen, die Sie wahrscheinlich tun.

Nun zu einigen Feinheiten.

Erstens ncharund nvarcharSpalten speichern Daten immer mit UCS-2. Dies bedeutet, dass genau zwei Bytes pro Zeichen verwendet werden und jedes Unicode-Zeichen in der mehrsprachigen Basisebene (BMP) durch ein ncharoder- nvarcharFeld gespeichert werden kann . Es ist jedoch nicht der Fall, dass ein Unicode-Zeichen gespeichert werden kann. Laut Wikipedia liegen die Codepunkte für ägyptische Hieroglyphen beispielsweise außerhalb des BMP. Es gibt daher Unicode-Zeichenfolgen, die in UTF-8 dargestellt werden können, und andere echte Unicode-Codierungen, die nicht in einem SQL Server ncharoder nvarcharFeld gespeichert werden können , und Zeichenfolgen, die in ägyptischen Hieroglyphen geschrieben sind, gehören dazu. Glücklicherweise schreiben Ihre Benutzer wahrscheinlich nicht in dieses Skript, aber es ist etwas zu beachten!

Ein weiterer verwirrend , aber interessanter Punkt , dass andere Plakate hervorgehoben haben , ist , dass charund varcharFelder zwei Bytes pro Zeichen für bestimmte Zeichen verwendet werden können , wenn die Sortierungscodepage es erfordert. (Martin Smith gibt ein hervorragendes Beispiel, in dem er zeigt, wie Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS dieses Verhalten zeigt. Probieren Sie es aus.)

UPDATE: Ab SQL Server 2012 gibt es endlich Codepages für UTF-16 , zum Beispiel Latin1_General_100_CI_AS_SC, die wirklich den gesamten Unicode-Bereich abdecken können.

PeterAllenWebb
quelle
14
  • char: Zeichendaten fester Länge mit einer maximalen Länge von 8000 Zeichen.
  • nchar: Unicode-Daten fester Länge mit einer maximalen Länge von 4000 Zeichen.
  • Char = 8 Bit Länge
  • NChar = 16 Bit Länge
ss.
quelle
charkonnte keine 8-Bit-Länge haben. Die Länge muss nicht gespeichert werden, und die feste Länge kann bis zu 8000 Zeichen betragen.
John B. Lambe
12

nchar[(n)] (Volkscharakter)

  • Unicode- Zeichenfolgendaten mit fester Länge .
  • n Definiert die Zeichenfolgenlänge und muss einen Wert zwischen 1 und 4.000 haben.
  • Die Speichergröße beträgt das Zweifache von nBytes.

nvarchar [(n | max)] (Nationaler Charakter variiert.)

  • Unicode- Zeichenfolgendaten variabler Länge .
  • n Definiert die Zeichenfolgenlänge und kann einen Wert zwischen 1 und 4.000 haben.
  • max gibt an, dass die maximale Speichergröße 2 ^ 31-1 Byte (2 GB) beträgt.
  • Die Speichergröße in Bytes beträgt das Zweifache der tatsächlichen Länge der eingegebenen Daten + 2 Bytes

char [(n)] (Charakter)

  • non-UnicodeZeichenfolgendaten mit fester Länge .
  • n Definiert die Zeichenfolgenlänge und muss einen Wert zwischen 1 und 8.000 haben.
  • Die Speichergröße beträgt nBytes.

varchar [(n | max)] (Zeichen variieren)

  • Nicht-Unicode- Zeichenfolgendaten variabler Länge .
  • n Definiert die Zeichenfolgenlänge und kann einen Wert zwischen 1 und 8.000 haben.
  • max gibt an, dass die maximale Speichergröße 2 ^ 31-1 Byte (2 GB) beträgt.
  • Die Speichergröße ist die tatsächliche Länge der eingegebenen Daten + 2 Bytes.
Rasel
quelle
7

Die Unterschiede sind:

  1. n [var] char speichert Unicode, während [var] char nur Einzelbytezeichen speichert.
  2. [n] char erfordert eine feste Anzahl von Zeichen mit der genauen Länge, während [n] varchar eine variable Anzahl von Zeichen bis einschließlich der definierten Länge akzeptiert.

Ein weiterer Unterschied ist die Länge. Sowohl nchar als auch nvarchar können bis zu 4.000 Zeichen lang sein. Und char und varchar können bis zu 8000 Zeichen lang sein. Für SQL Server können Sie jedoch auch einen [n] varchar (max) verwenden, der bis zu 2.147.483.648 Zeichen verarbeiten kann. (Zwei Gigabyte, eine vorzeichenbehaftete 4-Byte-Ganzzahl.)

Wim zehn Brink
quelle
7

nchar benötigt mehr Platz als nvarchar.

z.B,

Ein nchar (100) speichert immer 100 Zeichen, auch wenn Sie nur 5 eingeben. Die verbleibenden 95 Zeichen werden mit Leerzeichen aufgefüllt. Wenn Sie 5 Zeichen in einem nvarchar (100) speichern, werden 5 Zeichen gespeichert.

Venkataraman R.
quelle
6
Nicht ganz richtig, da Sie ein Zeichen (100) mit bis zu 100 Zeichen füllen müssen. Sie würden dies verwenden, wenn Sie z. B. Telefonnummern in Ihrer Datenbank speichern oder Nummern mit einer festen Länge bestellen. Da die Feldlänge fest ist, haben Sie keine Wahl, sie bis zur maximalen Anzahl von Zeichen zu füllen. Wenn alle Ihre Daten 100 Zeichen pro Datensatz enthalten, benötigt ein Zeichen (100) weniger Speicherplatz als ein Zeichen (100), da keine Längenangabe erforderlich ist: Jeder Wert würde genau 100 Zeichen umfassen.
Wim ten Brink
5

nchar (10) ist eine Unicode-Zeichenfolge mit fester Länge der Länge 10. nvarchar (10) ist eine Unicode-Zeichenfolge mit variabler Länge und einer maximalen Länge von 10. Normalerweise verwenden Sie die erstere, wenn alle Datenwerte 10 Zeichen und die letztere sind wenn die Längen variieren.

Jason Kresowaty
quelle
Falscher Vergleich - Frage bezieht sich auf nchar und varchar, nicht auf nchar und nvarchar.
Luke Bennett
4
  • nchar hat eine feste Länge und kann Unicode-Zeichen enthalten. Es verwendet zwei Bytes Speicher pro Zeichen.

  • varchar hat eine variable Länge und kann keine Unicode-Zeichen enthalten. Es wird ein Byte-Speicher pro Zeichen verwendet.

Manu
quelle
Falsch. Unicode kann (im Allgemeinen) 1 bis 4 Bytes für jedes Zeichen verwenden. Ein Varchar kann auch Unicode enthalten, wird jedoch nicht als Unicode erkannt. Infolgedessen wird ein Varchar für die Unicode-Speicherung als unzuverlässig angesehen. (Zumal das Risiko besteht, dass der Code, der auf das Feld zugreift, es falsch übersetzt.)
Wim ten Brink
@ Alex: Ich denke, Sie haben Ihren Standpunkt klargestellt, aber ich stimme Ihnen immer noch nicht zu. Was Sie sagen ist, dass ein int einen Long halten kann, wenn der Long kleiner als 2 ^ 32 ist. Dies ist nicht nur "unzuverlässig", sondern eine inhärente Einschränkung, die es unmöglich macht, den gesamten Wertebereich abzudecken.
Manu
4
@Workshop Alex: Falsch. Unicode codiert als UCS-2(was zufällig die von SQL Server verwendete Codierung ist) speichert jedes Zeichen in genau zwei Bytes, siehe 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 kann die SCSU-Komprimierung verwenden, komprimiert jedoch weiterhin die UCS-2-codierten Unicode-Zeichenfolgen: msdn.microsoft.com/en-us/library/ee240835.aspx
Remus Rusanu
2

NVARCHAR kann Unicode-Zeichen speichern und benötigt 2 Bytes pro Zeichen.

Gustavo Rubio
quelle
1
FALSCH! Unicode verwendet zwischen 1 und 4 Bytes pro Zeichen! Viele Leute vergessen das! Sogar die Verwendung von UTF-16 kann dazu führen, dass einige Zeichen 4 Bytes anstelle von 2 benötigen, obwohl die gemeinsame Länge 2 Bytes beträgt. Bestimmte andere Unterformate von Unicode benötigen möglicherweise sogar mehr als 4 Byte!
Wim ten Brink
7
@WimtenBrink - Die Frage bezieht sich auf SQL Server und benötigt nvarcharimmer 2 Bytes pro Zeichen.
Martin Smith
@Wim, Sie haben Recht, es gibt mehrere Codierungen für Unicode, die eine unterschiedliche Anzahl von Bytes erzeugen können. In SQL Server können Sie jedoch keine Auswahl für die Unicode-Codierung treffen. SQL Server vor 2012 verwendete nur UCS-2 mit einer Breite von zwei Bytes, sodass Martin zum Zeitpunkt des Schreibens der Antwort korrekt war. Wie bereits in anderen Antworten erwähnt, bietet SQL Server 2012 jetzt UTF-16, also zwei Bytes für viele Zeichen (die in der mehrsprachigen Unicode-Grundebene) und vier Bytes für andere.
Concrete Gannet