Jakie są główne różnice w wydajności między typami danych varchar i nvarchar SQL Server?

236

Pracuję nad bazą danych dla małej aplikacji internetowej w mojej szkole SQL Server 2005.
Widzę kilka szkół myślenia na temat varcharvs nvarchar:

  1. Używaj, varcharchyba że masz do czynienia z wieloma danymi międzynarodowymi, a następnie używaj nvarchar.
  2. Po prostu użyj nvarchardo wszystkiego.

Zaczynam dostrzegać zalety widzenia 2. Wiem, że nvarchar zajmuje dwa razy więcej miejsca, ale to niekoniecznie wielka sprawa, ponieważ będzie to przechowywać dane tylko dla kilkuset studentów. Wydaje mi się, że najłatwiej byłoby nie przejmować się tym i po prostu pozwolić wszystkim korzystać z nvarchar. A może brakuje mi czegoś?

Jason Baker
źródło
podobne pytanie tutaj: stackoverflow.com/questions/312170/... EDYCJA autorstwa le dorfier: co ciekawe doszło do dokładnie przeciwnego wniosku.
Booji Boy
6
odniesienie do znacznie szerszego wątku, który doszedł do przeciwnego wniosku. stackoverflow.com/questions/312170/…
dkretz
2
Jason: Mam nadzieję, że nie jest to niewłaściwa prośba, ale czy możesz rozważyć zmianę zaakceptowanej odpowiedzi na gbn's . Odpowiedź JoeBarone jest strasznie błędna z wielu powodów. „Dopuszczenie” wprowadza w błąd nowicjuszy w podejmowaniu złych wyborów. „Zawsze używać NVARCHAR” jest niepotrzebne i nieekonomiczne , i może mieć bardzo negatywny wpływ na wydajność i koszty / budżety sprzętu. Kilka rzędów, nawet kilka tysięcy, nie będzie miało znaczenia. Ale systemy rosną szybciej, niż ludzie się spodziewają, więc obecna akceptowana odpowiedź jest niekorzystna dla społeczności. Dziękuję Ci.
Solomon Rutzky

Odpowiedzi:

140

Zawsze używaj nvarchar.

W większości aplikacji nigdy nie będziesz potrzebować znaków dwubajtowych. Jeśli jednak potrzebujesz obsługi języków dwubajtowych i masz obsługę tylko jednego bajtu w schemacie bazy danych, powrót i modyfikacja w całej aplikacji jest naprawdę kosztowna.

Koszt migracji jednej aplikacji z varchar do nvarchar będzie znacznie większy niż odrobina dodatkowego miejsca na dysku, którego będziesz używać w większości aplikacji.

Joe Barone
źródło
4
znacznie trudniej jest wrócić i dodać obsługę wielojęzycznych wiadomości tekstowych, stref czasowych, jednostek miary i waluty, więc każdy MUSI zawsze kodować je w swojej aplikacji od pierwszego dnia, ZAWSZE (nawet jeśli jest to tylko na stronie głównej aplikacja)!
KM.
82
Co z wielkością indeksu, zużyciem pamięci itp.? Zakładam, że zawsze używasz int, kiedy możesz używać tinyint zbyt „na wszelki wypadek”?
gbn
99
Zawsze kodowanie / planowanie witryny wielojęzycznej (kiedy nie masz pojęcia, że ​​będziesz jej kiedykolwiek potrzebować) jest jak mówienie wszystkim młodym dorosłym, że powinni kupić duży 8-osobowy, żaroodporny SUV do swojego pierwszego samochodu ... w końcu , mogą się kiedyś pobrać i mieć 6 dzieci,. Wolę cieszyć się wydajnością i wydajnością, gdy mogę, i płacić cenę za aktualizację, kiedy / jeśli jej potrzebuję.
EJ Brennan
4
@cbmeeks: ja nie kod dla co ja nie wiem. Ale jeśli możesz go używać bez zauważalnego
spadku
60
Zwykle, gdy ludzie rozpoczynają odpowiedź słowem „Zawsze”, należy zignorować wszystko, co nastąpi później. (Zauważ, że zacząłem to stwierdzenie słowem „zwykle” :)
Brandon Moore
226

Miejsce na dysku nie jest problemem ... ale pamięć i wydajność będą. Podwójna liczba odczytów strony, podwójny rozmiar indeksu, dziwne LIKE i = stałe zachowanie itp

Czy potrzebujesz przechowywać skrypt chiński itp.? Tak lub nie...

I od MS BOL „ Efekty przechowywania i wydajności Unicode

Edytuj :

Ostatnie pytanie SO podkreślające, jak niska wydajność nvarchar może być ...

SQL Server używa wysokiego procesora podczas wyszukiwania wewnątrz ciągów nvarchar

gbn
źródło
19
+1, jeśli twoja aplikacja zostanie wprowadzona na rynek międzynarodowy, będziesz mieć wiele innych problemów związanych z wyszukiwaniem / zamianą na nvarchar: wielojęzyczny tekst / wiadomości, strefy czasowe, jednostki miary i waluta
KM.
2
Ale co, jeśli czasami trzeba przechowywać obce nazwisko, takie jak José lub Bjørn?
Qwertie
7
@Qwertie: następnie używasz nvarchar. Czego nie robisz, używaj go niepotrzebnie. Te dwie nazwy i tak pasują do
varchara
6
Mówienie, że miejsce na dysku nie jest problemem, nie jest prawdziwe dla wszystkich. Naiwnie używaliśmy nvarchar niepotrzebnie w dużej aplikacji bankowej z miliardami zapisów przechowywanych przez wiele lat. Dzięki drogiej pamięci masowej opartej na sieci SAN z replikacją, kopiami zapasowymi i odzyskiwaniem po awarii może to w rzeczywistości przekładać się na miliony dolarów kosztów nvarchar vs. varchar. Nie wspominając o tym, że istnieje duży (100%) wpływ na wydajność, który wymaga odczytu dwa razy więcej bajtów z dysku na każdy odczyt.
codemonkey
2
@codemonkey i inni: Zrobiłem, co mogłem, aby rozwiązać problem marnowanej przestrzeni w sposób holistyczny w następującym artykule: Dysk jest tani! ORLY? (wymagana jest jednak bezpłatna rejestracja). Artykuł ma pomóc w zapobieganiu sytuacji, w której napotkał klucz szyfrujący dotyczący kosztownej pamięci masowej na poziomie przedsiębiorstwa.
Solomon Rutzky
59

Bądź konsekwentny! DOŁĄCZENIE VARCHAR do NVARCHAR ma duży hit wydajności.

Thomas Harlan
źródło
115
Jeśli wykonujesz sprzężenia na polach znaków, twoja baza danych prawdopodobnie ma gorsze problemy niż to, czy ogólnie używasz nvarchar czy varchar.
Brandon Moore
@Thomas Harlan Prosty test pokazuje mi, że nie ma konkretnej różnicy między łączeniem nvarcharsię varchara konwersją nvarchardo varchari dołączaniem do varchar. Chyba że oczywiście chciałeś zachować spójność w typach kolumn, a nie dołączać.
ajeh 12.04.17
1
@ajeh and Thomas: 1) „proste” testy często wprowadzają w błąd, ponieważ nie obejmują odmian powodujących różnice w zachowaniu. 2) Jeśli zauważysz drastyczne pogorszenie wydajności podczas mieszania, VARCHARi NVARCHARpowinno to wynikać z indeksowania VARCHARkolumny wraz z rodzajem sortowania zastosowanym dla tej kolumny (i stąd indeksu). Szczegółowo omawiam ten temat w następującym poście na blogu: Wpływ na indeksy podczas mieszania typów VARCHAR i NVARCHAR .
Solomon Rutzky
44

nvarchar będzie miał znaczne obciążenie pamięci, pamięci, zestawu roboczego i indeksowania, więc jeśli specyfikacje wskazują, że tak naprawdę nigdy nie będzie to konieczne, nie przejmuj się.

Nie miałbym twardej i szybkiej reguły „zawsze nvarchar”, ponieważ może to być kompletne marnotrawstwo w wielu sytuacjach - szczególnie ETL z ASCII / EBCDIC lub identyfikatorów i kolumn kodu, które często są kluczami i kluczami obcymi.

Z drugiej strony istnieje wiele przypadków kolumn, w których z pewnością zada mi się to pytanie wcześniej, a jeśli nie otrzymam szybkiej i szybkiej odpowiedzi od razu, utworzę kolumnę nvarchar.

Cade Roux
źródło
26

Waham się, aby dodać tutaj kolejną odpowiedź, ponieważ jest już ich sporo, ale należy podać kilka kwestii, które albo nie zostały przedstawione, albo nie zostały jasno określone.

Po pierwsze: Czy nie zawsze używać NVARCHAR. Jest to bardzo niebezpieczne i często kosztowne podejście / podejście. I nie jest lepiej powiedzieć „ Nigdy nie używaj kursorów”, ponieważ czasami są one najskuteczniejszym sposobem rozwiązania określonego problemu, a wspólne obejście wykonywania WHILEpętli prawie zawsze będzie wolniejsze niż poprawnie wykonany Kursor.

Termin „zawsze” powinien być używany tylko wtedy, gdy zaleca się „zawsze robić to, co jest najlepsze w danej sytuacji”. To prawda, że ​​często jest to trudne do ustalenia, szczególnie gdy próbuje się zrównoważyć krótkoterminowe zyski z czasu programowania (kierownik: „potrzebujemy tej funkcji - o której jeszcze nie wiedzieliście - tydzień temu!”) Z długim -terminowe koszty utrzymania (kierownik, który początkowo naciskał na zespół, aby ukończył 3-miesięczny projekt w 3-tygodniowym sprincie: „dlaczego mamy te problemy z wydajnością? Jak moglibyśmy zrobić X, który nie ma elastyczności? Nie możemy sobie pozwolić sprint lub dwa, aby to naprawić. Co możemy zrobić w ciągu tygodnia, abyśmy mogli wrócić do naszych priorytetowych przedmiotów? I zdecydowanie musimy spędzić więcej czasu na projektowaniu, aby tak się nie stało! ”).

Po drugie: odpowiedź @ gbn dotyczy kilku bardzo ważnych punktów, które należy wziąć pod uwagę przy podejmowaniu pewnych decyzji dotyczących modelowania danych, gdy ścieżka nie jest w 100% jasna. Ale jest jeszcze więcej do rozważenia:

  • rozmiar plików dziennika transakcji
  • czas potrzebny do replikacji (jeśli używasz replikacji)
  • czas potrzebny na ETL (jeśli ETLing)
  • czas potrzebny na wysłanie logów do zdalnego systemu i przywrócenie (jeśli używasz Log Log)
  • rozmiar kopii zapasowych
  • czas potrzebny na wykonanie kopii zapasowej
  • czas potrzebny na przywrócenie (może to być kiedyś ważne ;-)
  • rozmiar potrzebny do tempdb
  • wydajność wyzwalaczy (dla wstawionych i usuniętych tabel przechowywanych w tempdb)
  • wydajność wersjonowania wierszy (jeśli używasz SNAPSHOT ISOLATION, ponieważ magazyn wersji jest w tempdb)
  • możliwość uzyskania nowego miejsca na dysku, gdy dyrektor finansowy poinformuje, że w zeszłym roku wydał 1 milion USD na SAN, więc nie autoryzuje kolejnych 250 000 USD na dodatkowe miejsce do przechowywania
  • czas potrzebny na wykonanie operacji INSERT i UPDATE
  • czas potrzebny na utrzymanie indeksu
  • itp. itp. itd.

Marnowanie przestrzeni ma ogromny efekt kaskadowy na cały system. Napisałem artykuł szczegółowo opisujący ten temat: Dysk jest tani! ORLY? (wymagana darmowa rejestracja; przepraszam, nie kontroluję tych zasad).

Po trzecie: chociaż niektóre odpowiedzi nieprawidłowo koncentrują się na aspekcie „jest to mała aplikacja”, a niektóre prawidłowo sugerują „wykorzystanie tego, co jest właściwe”, żadna z odpowiedzi nie przedstawiła rzeczywistych wskazówek dla PO Ważny szczegół wymieniony w pytaniu jest to, że jest to strona internetowa ich szkoły. Wspaniały! Możemy więc zasugerować, że:

  • Pola dla nazw studentów i / lub wydziałów powinny być prawdopodobnie,NVARCHAR ponieważ z czasem coraz bardziej prawdopodobne staje się pojawienie się nazwisk z innych kultur w tych miejscach.
  • Ale dla adresu i nazwy miasta? Cel aplikacji nie został określony (byłoby to pomocne), ale zakładając, że dane adresowe, jeśli takie istnieją, odnoszą się tylko do określonego regionu geograficznego (tj. Jednego języka / kultury), należy użyć VARCHARodpowiedniej strony kodowej (która jest określany na podstawie sortowania pola).
  • Jeśli przechowujesz kody ISO państwa i / lub kraju (nie musisz przechowywać INT/ TINYINTponieważ kody ISO mają ustaloną długość, są czytelne dla człowieka i no cóż, standardowe :) użyj CHAR(2)do kodów dwuliterowych i CHAR(3)jeśli używasz kodów 3-literowych. I rozważ użycie binarnego sortowania, takiego jak Latin1_General_100_BIN2.
  • Jeśli przechowujesz kody pocztowe (tj. Kody pocztowe), używaj, VARCHARponieważ jest to międzynarodowy standard, aby nigdy nie używać żadnej litery poza AZ. I tak, nadal używaj, VARCHARnawet jeśli przechowujesz tylko amerykańskie kody pocztowe, a nie INT, ponieważ kody pocztowe nie są liczbami, są łańcuchami, a niektóre z nich mają wiodące „0”. I rozważ użycie binarnego sortowania, takiego jak Latin1_General_100_BIN2.
  • Jeśli przechowujesz adresy e-mail i / lub adresy URL, użyj, NVARCHARponieważ oba mogą teraz zawierać znaki Unicode.
  • i tak dalej....

Po czwarte: teraz, gdy NVARCHARdane zajmują dwa razy więcej miejsca niż potrzeba dla danych, które ładnie się pasują VARCHAR(„ładnie pasuje” = nie zamienia się w „?”) I jakoś, jakby magicznie, aplikacja się rozrosła a teraz są miliony rekordów w co najmniej jednym z tych pól, w których większość wierszy jest standardowym kodem ASCII, ale niektóre zawierają znaki Unicode, więc musisz je zachować NVARCHAR, rozważ następujące kwestie:

  1. Jeśli używasz programu SQL Server 2008 - 2016 RTM i korzystasz z wersji Enterprise Edition, LUB jeśli korzystasz z programu SQL Server 2016 z dodatkiem SP1 (który udostępnił kompresję danych we wszystkich edycjach) lub nowszym, możesz włączyć kompresję danych . Kompresja danych może (ale nie zawsze) kompresuje dane NCHARi NVARCHARpola Unicode . Czynnikami determinującymi są:

    1. NCHAR(1 - 4000)i NVARCHAR(1 - 4000)użyj standardowego schematu kompresji dla Unicode , ale tylko w SQL Server 2008 R2, ORAZ tylko dla danych IN ROW, a nie PRZEKROCZENIA! To wydaje się być lepsze niż zwykły algorytm kompresji ROW / PAGE.
    2. NVARCHAR(MAX)i XML(i chyba również VARBINARY(MAX), TEXTi NTEXT) dane, które są w rzędzie (nie od wiersza LOB lub przelewowe strony) mogą być co najmniej PAGE sprężonego ale nie Rów ściśnięta. Oczywiście kompresja PAGE zależy od wielkości wartości w wierszu: przetestowałem za pomocą VARCHAR (MAX) i zobaczyłem, że wiersze 6000 znaków / bajtów nie ulegają kompresji, ale wiersze 4000 znaków / bajtów tak.
    3. Wszelkie dane OFF ROW, LOB lub OVERLOW = Brak kompresji dla Ciebie!
  2. Jeśli używasz programu SQL Server 2005 lub 2008-2016 RTM, a nie wersji Enterprise Edition, możesz mieć dwa pola: jedno VARCHARi jedno NVARCHAR. Załóżmy na przykład, że przechowujesz adresy URL, które w większości są podstawowymi znakami ASCII (wartości 0–127), a zatem pasują do VARCHAR, ale czasami mają znaki Unicode. Twój schemat może zawierać następujące 3 pola:

      ...
      URLa VARCHAR(2048) NULL,
      URLu NVARCHAR(2048) NULL,
      URL AS (ISNULL(CONVERT(NVARCHAR([URLa])), [URLu])),
      CONSTRAINT [CK_TableName_OneUrlMax] CHECK (
                        ([URLa] IS NOT NULL OR [URLu] IS NOT NULL)
                    AND ([URLa] IS NULL OR [URLu] IS NULL))
    );

    W tym modelu WYBIERASZ tylko z [URL]kolumny obliczeniowej. Do wstawiania i aktualizowania decydujesz, którego pola użyć, sprawdzając, czy konwersja zmienia wartość wejściową, która musi być NVARCHARtypu:

    INSERT INTO TableName (..., URLa, URLu)
    VALUES (...,
            IIF (CONVERT(VARCHAR(2048), @URL) = @URL, @URL, NULL),
            IIF (CONVERT(VARCHAR(2048), @URL) <> @URL, NULL, @URL)
           );
  3. Możesz GZIP przychodzące wartości do, VARBINARY(MAX)a następnie rozpakuj po wyjściu:

    • W przypadku SQL Server 2005 - 2014: możesz użyć SQLCLR. SQL # (biblioteka SQLCLR, którą napisałem) zawiera Util_GZip i Util_GUnzip w wersji darmowej
    • W przypadku programu SQL Server 2016 i nowszych: można korzystać z wbudowanych funkcji COMPRESSi DECOMPRESSfunkcji, które są także GZip.
  4. Jeśli korzystasz z programu SQL Server 2017 lub nowszego, możesz sprawdzić, czy tabela stanie się Clustered Columnstore Index.

  5. Chociaż nie jest to jeszcze opłacalna opcja, SQL Server 2019 wprowadza natywną obsługę UTF-8 w VARCHAR/ CHARtypy danych. Obecnie jest z nim zbyt wiele błędów, aby można go było użyć, ale jeśli zostaną naprawione, jest to opcja w niektórych scenariuszach. Zapoznaj się z moim postem „ Natywna obsługa UTF-8 w programie SQL Server 2019: Zbawiciel czy fałszywy prorok? ”, Aby uzyskać szczegółową analizę tej nowej funkcji.

Solomon Rutzky
źródło
7
Powolne klaskanie. Po prostu zdziwiłem się, że „zawsze używaj nvarchar” dostało 140 głosów, a to nie. Świetna robota w tym poście.
schizoid04
1
@ schizoid04 Thanks. Aby być uczciwym, zaakceptowana odpowiedź została opublikowana 7 lat przed moim, więc jest duży ruch, który głosował na nią (i / lub różne inne), który nigdy nie wrócił do ponownej oceny. Mimo to stanowi bardzo solidny kontrapunkt wobec teorii „mądrości tłumu”, która napędza fora oparte na głosowaniu. Tam jest za dużo dezinformacji. Na przykład to na DBA.SE. Inna odpowiedź, zaakceptowana przed opublikowaniem mojej, jest „poprawna” według najwęższej z definicji, wprowadza w błąd i zawiera informacje, które obalam w mojej, ale wciąż przewyższa ona moją.
Solomon Rutzky
22

W przypadku Twojej aplikacji nvarchar jest w porządku, ponieważ rozmiar bazy danych jest mały. Powiedzenie „zawsze używaj nvarchar” jest ogromnym uproszczeniem. Jeśli nie musisz przechowywać takich rzeczy jak Kanji lub inne zwariowane postacie, użyj VARCHAR, zajmie to o wiele mniej miejsca. Mój poprzednik w mojej obecnej pracy zaprojektował coś przy użyciu NVARCHAR, gdy nie było to potrzebne. Niedawno zmieniliśmy go na VARCHAR i zaoszczędziliśmy 15 GB na tym samym stole (do czego był bardzo napisany). Ponadto, jeśli masz indeks w tej tabeli i chcesz dołączyć tę kolumnę lub utworzyć indeks złożony, właśnie zwiększyłeś rozmiar pliku indeksu.

Po prostu rozważ swoją decyzję; w rozwoju SQL i definicjach danych rzadko wydaje się, że istnieje „domyślna odpowiedź” (oczywiście poza unikaniem kursorów za wszelką cenę).

WebMasterP
źródło
10

Ponieważ Twoja aplikacja jest niewielka, korzystanie z nvarchar w porównaniu z varchar zasadniczo nie powoduje znacznego wzrostu kosztów, a jeśli chcesz przechowywać dane w trybie Unicode, oszczędzasz sobie potencjalnych problemów.

tbreffni
źródło
8

Ogólnie rzecz biorąc; Zacznij od najdroższego typu danych, który ma najmniejsze ograniczenia. Umieść go w produkcji . Jeśli wydajność zaczyna być problemem, dowiedz się, co faktycznie jest przechowywane w tych nvarcharkolumnach. Czy są tam jakieś postacie, które nie pasowałyby varchar? Jeśli nie, zmień na varchar. Nie próbuj wstępnie optymalizować, zanim będziesz wiedział, gdzie jest ból. Domyślam się, że wybór pomiędzy nvarchar / varchar nie jest tym, co spowolni twoją aplikację w dającej się przewidzieć przyszłości. Będą też inne części aplikacji, w których dostrajanie wydajności zapewni znacznie więcej pieniędzy .

Kjetil Klaussen
źródło
7

Przez ostatnie kilka lat wszystkie nasze projekty wykorzystywały NVARCHAR do wszystkiego, ponieważ wszystkie te projekty są wielojęzyczne. Zaimportowane dane ze źródeł zewnętrznych (np. Plik ASCII itp.) Są konwertowane do formatu Unicode przed włożeniem do bazy danych.

Nie spotkałem się jeszcze z żadnymi problemami związanymi z wydajnością z większych indeksów itp. Indeksy zużywają więcej pamięci, ale pamięć jest tania.

Niezależnie od tego, czy korzystasz z procedur przechowywanych, czy konstruujesz SQL w locie, upewnij się, że wszystkie stałe ciągów są poprzedzone N (np. SET @foo = N'Hello world. ';), Aby stała była również Unicode. Pozwala to uniknąć konwersji typu łańcucha w czasie wykonywania.

YMMV.

devstuff
źródło
4
Prawdopodobnie nie masz kilkuset milionów rekordów w tabelach, z którymi pracujesz. Zgadzam się, że dla większości aplikacji domyślna nvarchar jest w porządku, ale nie wszystkie.
Brandon Moore
7

Mogę o tym mówić z doświadczenia, strzeżcie się nvarchar. O ile nie jest to absolutnie wymagane, ten typ pola danych niszczy wydajność w większej bazie danych. Odziedziczyłem bazę danych, która szkodziła pod względem wydajności i przestrzeni. Udało nam się zmniejszyć rozmiar bazy danych 30 GB o 70%! Wprowadzono kilka innych modyfikacji, aby poprawić wydajność, ale jestem pewien, że varcharznacznie pomogły również w tym. Jeśli Twoja baza danych ma potencjał do powiększenia tabel do ponad miliona rekordów, trzymaj się z dala od nvarcharwszelkich kosztów.

JA
źródło
4

Często zadaję sobie to pytanie w pracy:

  • Kanały FTP z zapasami i cenami - opisy produktów i inne teksty znajdowały się w nvarchar, gdy varchar działał poprawnie. Przekształcenie ich w varchar zmniejszyło rozmiar pliku prawie o połowę i naprawdę pomogło w przesyłaniu.

  • Powyższy scenariusz działał dobrze, dopóki ktoś nie umieścił znaku specjalnego w opisie przedmiotu (być może znak towarowy, nie pamiętam)

Nadal nie używam nvarchar za każdym razem nad varchar. Jeśli są jakieś wątpliwości lub potencjał dla znaków specjalnych, używam nvarchar. Uważam, że używam varchar głównie wtedy, gdy mam 100% kontrolę nad tym, co wypełnia pole.

K Richard
źródło
3

Dlaczego w całej tej dyskusji nie wspomniano o UTF-8? Możliwość przechowywania pełnego zakresu znaków Unicode nie oznacza, że ​​należy zawsze przydzielić dwa bajty na znak (lub „punkt kodowy”, aby użyć terminu UNICODE). Wszystkie ASCII to UTF-8. Czy SQL Server sprawdza dla pól VARCHAR (), że tekst jest ścisły ASCII (tj. Bit najwyższego bajtu zero)? Miałbym nadzieję, że nie.

Jeśli następnie chcesz zapisać Unicode i chcesz kompatybilność ze starszymi aplikacjami tylko ASCII, pomyślałbym, że użycie VARCHAR () i UTF-8 byłoby magiczną kulą: Zużywa więcej miejsca, gdy jest to konieczne.

Dla tych z was, którzy nie znają UTF-8, polecam podkład .

Tevya
źródło
2
To, co sugerujesz, może działać w przypadku niektórych aplikacji, ale należy również wziąć pod uwagę wpływ dodatkowej warstwy kodowania na sposób przetwarzania tekstu SQL. W szczególności zostaną przeprowadzone sortowania, wyszukiwanie i dopasowanie wzorców. A jeśli raporty są uruchamiane w bazie danych, standardowe narzędzia raportowania nie interpretują poprawnie znaków wielobajtowych. I może odbywać się import i eksport luzem. Myślę, że - w dłuższej perspektywie - ten program może sprawiać więcej kłopotów niż jest wart.
Jeffrey L Whitledge,
1
UTF-8 nie można przechowywać w kolumnach VARCHAR. MSSQL zawsze konwertuje dane UTF-8 na układanie kolumn. Jeśli zepsujesz sortowanie (np. Próbujesz zapisać CP1252 w Latin_1), konwersja nie zadziała i otrzymasz dodatkowe bajty w swoich danych. Może się wydawać, że działa dobrze, kiedy konwertujesz latin_1 na UTF-8 (po stronie aplikacji) i ponownie z powrotem na latin_1 (po stronie db), ale to tylko złudzenie. Możesz przekraść się przez automatyczną konwersję DB do sortowania kolumn, używając freetds i ustawiając protokół na mniej niż 7, ale tracisz możliwość zapytania do nvarchar.
chugadie
1
@chugadie i Tevya: ta odpowiedź jest trochę nonsensowna. SQL Server używa UCS-2 / UTF-16 tylko do przechowywania danych Unicode (tj. XML i Ntypy z prefiksem). Nie masz wyboru korzystania z UTF-8. Ponadto kodowania Unicode (UTF-8, UCS-2 / UTF-16 i UTF-32) nie można zastosować do pól VARCHAR.
Solomon Rutzky
2

Będą wyjątkowe sytuacje, gdy będziesz chciał celowo ograniczyć typ danych, aby upewnić się, że nie zawiera on znaków z określonego zestawu. Na przykład miałem scenariusz, w którym musiałem przechowywać nazwę domeny w bazie danych. Internacjonalizacja nazw domen nie była wówczas niezawodna, dlatego lepiej ograniczyć wprowadzanie danych na poziomie podstawowym i pomóc uniknąć potencjalnych problemów.

Chris Halcrow
źródło
1

Jeśli używasz NVARCHARtylko dlatego, że systemowa procedura przechowywana tego wymaga, najczęstsze wystąpienie jest niewytłumaczalne sp_executesql, a Twój dynamiczny SQL jest bardzo długi, lepiej byłoby z perspektywy wydajności wykonywać wszystkie operacje na łańcuchach (konkatenacja, zamiana itp.) W VARCHARkonwersji wynik końcowy NVARCHARi wprowadzenie go do parametru proc. Więc nie, nie zawsze używaj NVARCHAR!

ajeh
źródło