2009-03-04 7 views
59

Czy istnieje reguła, w której musimy używać typów Unicode?Kiedy należy używać NVARCHAR/NCHAR zamiast VARCHAR/CHAR w SQL Server?

Widziałem, że większość europejskich języków (niemiecki, włoski, angielski, ...) jest w porządku w tej samej bazie danych w kolumnach VARCHAR.

szukam czegoś podobnego:

  1. Jeśli masz chiński -> użyj NVARCHAR
  2. Jeśli masz niemieckim i arabskim -> użyj NVARCHAR

co z zestawień serwera/bazy danych?

Nie chcę używać zawsze NVARCHAR jak sugeruje tutaj What are the main performance differences between varchar and nvarchar SQL Server data types?

Odpowiedz

96

Prawdziwy powód, dla którego chcesz używać NVARCHAR, gdy masz różnych języków w tej samej kolumnie, musisz adresować kolumny w T-SQL bez dekodowania, chcesz mieć możliwość wyświetlania danych "natywnie" w SSMS, lub chcesz standaryzować na Unicode.

Jeśli traktujesz bazę danych jako pamięć masową, możliwe jest przechowywanie szerokich ciągów znaków i różnych (nawet o zmiennej długości) kodowań w VARCHAR (na przykład UTF-8). Problem pojawia się, gdy próbujesz kodować i dekodować, zwłaszcza jeśli strona kodowa jest różna dla różnych wierszy. Oznacza to również, że SQL Server nie będzie w stanie poradzić sobie z danymi w prosty sposób w celu wykonywania zapytań w T-SQL na (potencjalnie zmiennie) kodowanych kolumnach.

Użycie NVARCHAR omija to wszystko.

Polecam NVARCHAR dla każdej kolumny, która będzie zawierała wprowadzone przez użytkownika dane, które są względnie niezwiązane.

Polecam VARCHAR dla każdej kolumny, która jest kluczem naturalnym (jak tablica rejestracyjna pojazdu, SSN, numer seryjny, znacznik serwisowy, numer zamówienia, znak wywoławczy na lotnisku itp.) Lub wprowadzonym przez użytkownika, ale bardzo ograniczonym (jak numer telefonu) lub kod (ACTIVE/CLOSED, Y/N, M/F, M/S/D/W, itp.).Nie ma absolutnie żadnego powodu, aby używać NVARCHAR dla tych.

Więc do prostej reguły:

VARCHAR gdy gwarancją ograniczone NVARCHAR inaczej

+2

>> gdy masz różne języki w tej samej kolumnie .... To wszystko! –

+3

Należy zauważyć, że * "różne języki" * nie oznacza tylko, że różne wiersze mogą zawierać wartości z różnych języków. Oznacza to również, że domyślne sortowanie bazy danych (tj. Ustawienia narodowego maszyny serwera) różni się od ustawień regionalnych dowolnego komputera klienckiego. na przykład Maszyna serwerowa jest ustawiona na 'en-US', ale mój komputer jest ustawiony na' fr-US'. –

+0

@IanBoyd Ogólnie rzecz biorąc, zestawianie będzie bardzo problematyczne podczas mieszania języków w kolumnie i zwracania elementów w wielu językach w jednym zestawie i korzystania z tego sortowania do zamawiania. Sortowanie może również mieć wpływ na łączenie znaków, które będą traktowane jako jedno (węgierskie dz i ly): http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx http://stackoverflow.com/questions/7207590/sql-server-case-collation-issue - nvarchar nie rozwiąże tego problemu –

3

grecki musiałby UTF-8 na n typów kolumn: αβγ;)

10

Należy użyć nvarchar każdej chwili masz do przechowywania wielu Języki. Uważam, że musisz go używać w językach azjatyckich, ale nie cytuj mnie na nim.

Oto problem, jeśli weźmiesz na przykład język rosyjski i zapiszesz go w varcharze, wszystko będzie dobrze, o ile zdefiniujesz poprawną stronę kodową. Ale powiedzmy, że używasz domyślnej angielskiej instalacji sql, wtedy rosyjskie znaki nie będą obsługiwane poprawnie. Jeśli używasz NVARCHAR(), będą one obsługiwane poprawnie.

Edit

Ok niech sobie zacytować MSDN i maybee miałem specyficzne, ale nie chcesz, aby zapisać stronę więcej niż jednego kodu w kolumnie varcar, póki możesz nie należy

Kiedy masz do czynienia z danych tekstowych, które są przechowywanych w char, varchar, varchar (max) lub typu danych tekstowych, najważniejszym ograniczeniem rozważyć jest to, że tylko informacje z jednego strony kodowej mogą zostać zatwierdzone przez system. (Można przechowywać dane z wielu stron kodowych , ale nie jest to zalecane ). Dokładna strona kodowa używana do sprawdzania i zapisywania danych używana jest w zakresie sortowania kolumny. Jeśli zdefiniowanie poziomu kolumn na poziomie nie zostało zdefiniowane, używane jest sortowanie bazy danych . Aby określić stronę kodową , który jest używany dla danej kolumny, ty można korzystać z funkcji COLLATIONPROPERTY , jak pokazano w następujących przykłady kodu:

Oto kilka:

Ten przykład ilustruje fakt, że wiele ustawień narodowych, takich jak gruziński i hindi, nie ma stron kodowych, ponieważ one są są tylko opcjami w formacie Unicode.Te sortowania nie są odpowiednie dla kolumn, które korzystają z char, varchar, lub typ danych tekstu

Więc gruziński lub hindi naprawdę muszą być przechowywane jako nvarchar. Arabski jest również problemem:

Kolejny problem może wystąpić jest niezdolność do przechowywania danych, gdy nie wszystkie znaki, które chcesz wsparcia zawarte są w kodzie stronie. W wielu przypadkach system Windows uważa, że ​​konkretna strona kodowa jest jedną z "najlepszych" stron kodowych , co oznacza, że ​​jest bez gwarancji, że można polegać na stronie kodowej , aby obsłużyć cały tekst; to jest tylko najlepsza dostępna. Przykładem tego jest arabski skrypt: obsługuje szeroki wachlarz języków, , w tym Baluchi, Berber, Farsi, Kaszmirski, Kazachski, Kirgiski, Pashto, Sindhi, Ujgur, Urdu i inne. Wszystkie języki te mają dodatkowe znaków poza tymi w języku arabskim zdefiniowane w kodzie dla Windows strona 1256. Jeśli spróbujesz zapisać te dodatkowe znaki w kolumnie non-Unicode, który ma arabski sortowania, znaki są skonwertowane na znaki zapytania.

Należy pamiętać o używaniu Unicode, chociaż można przechowywać różne języki w jednej kolumnie, którą można sortować tylko za pomocą pojedynczego sortowania. Niektóre języki używają znaków łacińskich, ale nie sortują tak, jak inne języki łacińskie. Akcenty są tego dobrym przykładem, nie mogę sobie przypomnieć przykładu, ale był tam język wschodnioeuropejski, którego Y nie sortował tak jak angielski Y. Potem jest hiszpański ch, którego hiszpańscy użytkownicy muszą posortować po h.

Podsumowując, wszystkie problemy, z którymi musisz sobie poradzić w przypadku internalizacji. Uważam, że łatwiej jest po prostu używać znaków Unicode od samego początku, uniknąć dodatkowych konwersji i wykonać trafienie w kosmos. Stąd moje oświadczenie wcześniej.

+3

>> Powinieneś używać NVARCHAR kiedy tylko chcesz przechowywać wiele języków To nie jest prawda. Niemiecki i włoski i angielski dobrze pasują do tej samej tabeli z kolumnami VARCHAR. Dokładniej: –

+0

Zobacz http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx i http://stackoverflow.com/questions/7207590/sql-server-case-collation-issue dla przykładów z dz i ly po węgiersku. –

2

Josh mówi: ”.... Coś warto pamiętać podczas korzystania Unicode choć można przechowywać różne języki w jednej kolumnie można sortować tylko za pomocą pojedynczego sortowania.Jest kilka języków, które używają znaków łacińskich, ale nie sortują jak inne języki łacińskie.Króty to dobry przykład tego, nie mogę zapamiętać przykładu, ale było język wschodnioeuropejski, którego Y nie sortował jak angielski Y. Potem jest hiszpański ch, którego hiszpańscy użytkownicy muszą posortować po h. "

Jestem rodowitym hiszpański głośników i „ch” nie jest list, ale dwa „c” i „h” i hiszpański jest jak alfabet: abcdefghijklmn ñ opqrstuvwxyz Nie oczekujemy „ch” po " h "ale" i " Alfabet jest taki sam jak w języku angielskim z wyjątkiem kodu ñ lub HTML" & ntilde; "

Alex

+0

Witaj Alex, czy kiedykolwiek przechowywałeś różne języki w 1 kolumnie? W 1 tabeli mieliśmy różne kolumny dla różnych języków. –

+0

Prawdopodobnie odnoszą się do języka czeskiego. Mamy "ch" między "h" i "i" i jest to osobna litera alfabetu. – jahav

0

TL; DR;
Unicode - (nchar, nvarchar i ntext)
Non-unicode - (char, varchar i tekst).

From MSDN

Konfrontacje w SQL Server zapewniają sortowania zasady, sprawy, i akcent właściwości czułości dla danych. Sortowania używane z typami danych znakowych , takimi jak char i varchar, określają stronę kodową i odpowiadające im znaki, które mogą być reprezentowane dla tego typu danych o numerze .

Zakładając, że używasz domyślnego sortowania SQL_Latin1_General_CP1_CI_AS następnie SQL Poniższy skrypt powinien wydrukować wszystkie symbole, które można zmieścić w VARCHAR ponieważ wykorzystuje jeden bajt do przechowywania jednego znaku (256 ogółem), jeśli nie widzisz go na lista wydrukowana - potrzebujesz NVARCHAR.

declare @i int = 0; 
while (@i < 256) 
begin 
print cast(@i as varchar(3)) + ' '+ char(@i) collate SQL_Latin1_General_CP1_CI_AS 
print cast(@i as varchar(3)) + ' '+ char(@i) collate Japanese_90_CI_AS 
set @i = @i+1; 
end 

przypadku zmiany sortowania do powiedzmy japoński można zauważyć, że wszystkie te dziwne litery europejskie przekształcony normalne i niektórych symboli do ? znaków.

Unicode to standard mapowania punktów kodowych na znaki. Ponieważ jest przeznaczony do obsługi wszystkich znaków ze wszystkich języków świata , nie ma potrzeby używania różnych stron kodowych do obsługi różnych zestawów znaków . Jeśli przechowujesz dane znakowe, które odzwierciedlają wiele języków , zawsze używaj typów danych Unicode (nchar, nvarchar i ntext) zamiast typów danych innych niż Unicode (char, varchar i text).

W przeciwnym razie sortowanie będzie dziwne.

Powiązane problemy