Napisz różnice między varchar i nvarchar

59

Obecnie korzystamy z naszej bazy danych SQL Server 2012 varchari chcielibyśmy to zmienić nvarchar. Wygenerowałem skrypt, aby to zrobić.

Moje pytanie: czy są jakieś różnice w sposobie zapisywania danych w varcharkolumnach przez SQL Server nvarchar? Mamy wiele procedur zaplecza, o które się martwię.

Edycja:
Nie jestem pewien, czy to pomaga, ale kolumny nie mają indeksów, f / k ani ograniczeń.

Chris L.
źródło
1
Zobacz także dba.stackexchange.com/questions/162113/…
Aaron Bertrand

Odpowiedzi:

46

Musisz mieć pewność, że poprzedzisz literały ciągowe Unicode prefiksem N. Na przykład będą działać inaczej, jeśli typem danych bazowych jest NVARCHAR:

CREATE TABLE dbo.t(c NVARCHAR(32));

INSERT dbo.t(c) SELECT 'រៀន';
INSERT dbo.t(c) SELECT 'នរៀ';
INSERT dbo.t(c) SELECT N'រៀន';

SELECT c FROM dbo.t;

SELECT c FROM dbo.t WHERE c = 'រៀន';
SELECT c FROM dbo.t WHERE c = N'រៀន';

Wyniki:

c
----
??? -- not stored correctly
??? -- not stored correctly
រៀន -- stored correctly!

c
----
???
??? -- probably not expected, however all Unicode characters have been changed to ?

c
----
រៀន

W przypadku urządzeń przenośnych lub niszczejących przeglądarek, które zamiast rzeczywistych znaków Unicode wyświetlają znaki pola, wygląda to tak:

wprowadź opis zdjęcia tutaj

Aaron Bertrand
źródło
37

Największym problemem jest to, że nvarcharużywa 2 bajtów na znak, podczas gdy varcharużywa 1. W ten sposób nvarchar(4000)zużywa tyle samo miejsca do przechowywania co varchar(8000)*.

Oprócz wszystkich danych postaci wymagających dwukrotnie więcej miejsca do przechowywania, oznacza to również:

  • Konieczne może być użycie krótszych nvarcharkolumn, aby utrzymać wiersze w granicach 8060 bajtów / 8000 bajtów.
  • Jeśli używasz nvarchar(max)kolumn, zostaną one wypchnięte poza wiersz wcześniej niż varchar(max)byłoby to możliwe.
  • Być może będziesz musiał użyć krótszych nvarcharkolumn, aby pozostać w granicach 900-bajtowego limitu klucza indeksu (nie wiem, dlaczego chcesz używać tak dużego klucza indeksu, ale nigdy nie wiesz).

Poza tym praca z nvarcharniczym nie różni się, zakładając, że oprogramowanie klienckie jest przystosowane do obsługi Unicode. SQL Server będzie przejrzysty upconvert varcharsię nvarchar, dzięki czemu nie trzeba ściśle prefiks N dla napisowych chyba że używasz 2-bajtowy (tj Unicode), w dosłownym. Pamiętaj, że rzutowanie nvarcharna wyniki varbinarydaje inne wyniki niż robienie tego samego z varchar. Ważną rzeczą jest to, że nie będziesz musiał natychmiast zmieniać każdego literału varchar na literał nvarchar, aby aplikacja działała, co ułatwia proces.

* Jeśli używasz kompresji danych (wystarczy lekka kompresja wierszy, wymagana wersja Enterprise Edition przed SQL Server 2016 SP1 ), zwykle znajdziesz nchari nvarcharnie zajmie więcej miejsca niż chari varchar, z powodu kompresji Unicode (przy użyciu algorytmu SCSU) .

db2
źródło
17

Pomyśl, że następujące są główne różnice:

  1. Nvarchar przechowuje dane UNICODE. Jeśli masz wymagania dotyczące przechowywania danych UNICODE lub wielojęzycznych, wyborem jest nvarchar. Varchar przechowuje dane ASCII i powinien być Twoim typem danych do normalnego użytku.
  2. Jeśli chodzi o wykorzystanie pamięci, nvarchar używa 2 bajtów na znak, podczas gdy varchar używa 1.
  3. PRZYŁĄCZENIE VARCHAR do NVARCHAR ma znaczący wpływ na wydajność.
  4. Może wymagać prefiksu N podczas wstawiania danych: INSERT dbo.t (c) SELECT N'ʤ ʥ ʦ ʧ ʨ ';
  5. Niektórzy eksperci zalecają nvarchar zawsze, ponieważ: ponieważ wszystkie nowoczesne systemy operacyjne i platformy programistyczne używają Unicode wewnętrznie, używając nvarchar zamiast varchar, uniknie kodowania konwersji za każdym razem, gdy czytasz lub zapisujesz w bazie danych
rchacko
źródło
0

nvarchar był wymagany do replikacji scalania RDP z mobilnej bazy danych do SQL Server 2005. Również LTrim (), RTrim () i Trim () były często używane .

Nie wiem, czy to się zmieniło w ostatnich latach, czy nie, ale nvarchar jest teraz standardem używanym do logowania do witryny .NET Simple Membership w VS Pro 2017, używanej w wygenerowanej bazie danych.

Joseph Poirier
źródło
-3

Jeśli korzystasz z NVarchar zamiast Varchar i nie masz obowiązku obsługi MULTI-LINQUAL, zwiększysz pamięć dla DB, Kopie zapasowe (lokalne i zewnętrzne). Nowoczesne bazy danych powinny obsługiwać oba, a wszelkie trafienia konwersji powinny być uwzględnione w projekcie.

Bill Lindsay
źródło