Jakie są przypadki użycia wyboru CHAR zamiast VARCHAR w SQL?

270

Zdaję sobie sprawę, że CHAR jest zalecane, jeśli wszystkie moje wartości mają stałą szerokość. No i co z tego? Dlaczego po prostu wybrać VARCHAR dla wszystkich pól tekstowych, aby być bezpiecznym.

SkunkSpinner
źródło

Odpowiedzi:

386

Zasadniczo wybierz CHAR, jeśli wszystkie rzędy będą miały zbliżoną długość . Wybierz VARCHAR, gdy długość różni się znacznie. CHAR może być również nieco szybszy, ponieważ wszystkie rzędy mają tę samą długość.

Różni się w zależności od implementacji DB, ale ogólnie VARCHAR wykorzystuje jeden lub dwa dodatkowe bajty pamięci (dla długości lub zakończenia) oprócz rzeczywistych danych. Więc (zakładając, że używasz jednobajtowego zestawu znaków) przechowującego słowo „FooBar”

  • CHAR (6) = 6 bajtów (bez obciążenia)
  • VARCHAR (10) = 8 bajtów (2 bajty narzutu)
  • CHAR (10) = 10 bajtów (4 bajty narzutu)

Najważniejsze jest to, że CHAR może być szybszy i zajmować więcej miejsca dla danych o stosunkowo tej samej długości (w obrębie różnicy długości dwóch znaków).

Uwaga : Microsoft SQL ma 2 bajty narzutu dla VARCHAR. Może się to różnić od DB do DB, ale generalnie potrzebny jest co najmniej 1 bajt narzutu potrzebny do wskazania długości lub EOL na VARCHAR.

Jak zauważył Gaven w komentarzach, jeśli używasz wielobajtowego zestawu znaków o zmiennej długości, takiego jak UTF8, to CHAR przechowuje maksymalną liczbę bajtów niezbędną do przechowywania liczby znaków. Więc jeśli UTF8 potrzebuje maksymalnie 3 bajty do przechowywania znaku, to CHAR (6) zostanie ustalony na 18 bajtów, nawet jeśli przechowuje tylko znaki Latin1. W takim przypadku VARCHAR staje się znacznie lepszym wyborem.

Jim McKeeth
źródło
20
Innym powodem są podziały stron i fragmentacja. Miałem tabelę z IDEN PK, która uległa fragmentacji w 99% z powodu podziałów stron w kolumnach varchar. Bardzo aktywna tabela i z natury aplikacji nowy wiersz pusty wiersz zostałby utworzony, a następnie wypełniony. Char naprawił problem fragmentacji.
paparazzo
12
@Jim McKeeth - te obliczenia są prawdziwe tylko wtedy, gdy używasz zestawu znaków latin1. Ponieważ w dzisiejszych czasach większość ludzi powinna używać utf8, twoje kolumny CHAR zajmą średnio 3x miejsca jako VARCHAR, który przechowuje głównie znaki w podstawowej płaszczyźnie wielojęzycznej.
Gavin Towey
11
@JimMcKeeth tak, to dokładnie prawda. Ponieważ CHAR jest stałą długością, musi być zatem ustalony na maksymalnej możliwej przestrzeni, która może być wykorzystana. W UTF8 jest to 3 bajty na znak. W przypadku programu varchar w razie potrzeby można użyć 1-3 bajtów na znak. Jest to w podręczniku MySQL: dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html
Gavin Towey
3
Jaka jest różnica między ciągiem FooBar i varchar (100) a char (100)? Myślę, że lepiej pokazuje różnicę, tak? Nie?
Nenotlep
4
@GavinTowey SQLSERVER używa UCS-2 dla swoich typów danych NCHAR i NVARCHAR. To zawsze dwa bajty na znak.
1010
69

Jeśli pracujesz ze mną i pracujesz z Oracle, prawdopodobnie użyłbym cię varcharw prawie każdych okolicznościach. Założenie, że charzużywa mniej mocy obliczeniowej, niż varcharmoże być prawdą ... na razie ... ale silniki baz danych z czasem stają się lepsze, a tego rodzaju ogólna reguła tworzy przyszły „mit”.

Kolejna rzecz: nigdy nie widziałem problemu z wydajnością, ponieważ ktoś zdecydował się pójść varchar. Znacznie lepiej wykorzystasz swój czas, pisząc dobry kod (mniej wywołań bazy danych) i wydajny SQL (jak działają indeksy, jak optymalizator podejmuje decyzje, dlaczego jest existsszybszy niż inzwykle ...).

Ostatnia myśl: widziałem różnego rodzaju problemy z używaniem CHAR, ludzi szukających „”, gdy powinni szukać ”, lub osób szukających„ FOO ”, gdy powinni szukać„ FOO ”(tutaj jest kilka miejsc) lub ludzie, którzy nie przycinają końcowych spacji, lub błędy z Powerbuilderem dodającym do 2000 spacji do wartości zwracanej przez procedurę Oracle.

Ethan Post
źródło
20
Nie zgadzam się nieco z twoim pierwszym akapitem, ponieważ char może dostarczyć podpowiedzi, która może być przydatna dla optymalizatorów, nawet przyszłych, i może pomóc w komunikowaniu intencji kolumny. Ale +1 za trzeci akapit. Nienawidzę wszystkich dodatkowych miejsc. Pole powinno po prostu przechowywać wszystko, co w nim wprowadzę, bez wszystkich [objaśniających] wypełnień. Zasadniczo używam char, jeśli wszystkie dane mają być dokładnie tej samej długości, nie więcej i nie mniej, teraz i na zawsze. Jest to oczywiście bardzo rzadkie i zwykle jest char (1).
Jeffrey L. Whitledge
char dostarcza także wskazówek dla analityków i programistów ... ta liczba to x liczba znaków ... Jeśli zastanawiają się nad serializacją w innym formacie, może to być pomocne. (Byłem zmuszony do przechowywania sumy kontrolnej md5 w znaku w mssql, który nie miał typu Uuid ... i nigdy nie chciałem niczego <32 bajtów ... również nałożyło ograniczenie na kolumnę).
joefromct
31

Oprócz korzyści związanych z wydajnością CHARmożna zastosować, aby wskazać, że wszystkie wartości powinny być tej samej długości, np. Kolumna dla skrótów stanów USA.

Hank Gay
źródło
Lub kody krajów - mogą pomóc odróżnić użycie 2 lub 3-znakowego skrótu kodu kraju
Dan Field
Jeśli to naprawdę stała długość, to powinno istnieć ograniczenie wymuszające to. Chociaż jeśli użyjesz CHAR, musisz upewnić się, że twoje ograniczenia rabują wypełnienie.
jpmc26
18

Char jest trochę szybszy, więc jeśli masz kolumnę, której WIEDZIE będzie pewnej długości, użyj char. Na przykład przechowywanie (M) ale / (F) emale / (U) nieznany dla płci lub 2 znaki dla stanu USA.

Jarrett Meyer
źródło
4
Nie jestem pewien, czy to WSPANIAŁA odpowiedź, ponieważ ENUM zwykle ma o wiele większy sens, chociaż nie jestem pewien, jak szeroko obsługiwany jest ten typ (poza MySQL).
Bobby Jack
Wydaje mi się, że zbiór stanów niekoniecznie jest niezmienny, więc char (2) wydaje się o wiele bardziej odpowiedni niż wyliczenie.
Kearns
1
@Bobby Jack - Nie znam szczegółowych informacji o żadnej konkretnej implementacji wyliczenia SQL, ale pamiętaj, że wyliczenie przechowywane jako 4-bajtowa liczba całkowita może wymagać więcej miejsca niż kolumna char (1) lub char (2) z te same dane. W pewnym sensie wyliczenia są bardziej logiczne pod względem interpretacji, co może być przekonujące, ale wszystko w systemie RDBMS jest na pewnym poziomie abstrakcyjne i podlega predykatom zdefiniowanym dla tabel.
Jeffrey L Whitledge,
4
Zły przykład, ENUM jest najlepszy w tym przypadku. Lepszym przykładem może być trzyliterowy kod lotniska IATA
Andrew G. Johnson
5
@Andrew, nie wszystkie bazy danych obsługują typy danych ENUM. Na przykład MSSQLServer nie. Również ENUM, przechowywane jako int, zajmuje 4 bajty. CHAR (1) zajmuje 1 bajt, a NCHAR (1) zajmuje 2 bajty.
Jarrett Meyer
17

Czy NChar lub Char działają lepiej niż ich alternatywne warianty?

Świetne pytanie. Prosta odpowiedź brzmi „tak” w niektórych sytuacjach. Zobaczmy, czy można to wyjaśnić.

Oczywiście wszyscy wiemy, że jeśli utworzę tabelę z kolumną varchar (255) (nazwijmy tę kolumnę myColumn) i wstawię milion wierszy, ale wstawię tylko kilka znaków do myColumn dla każdego wiersza, tabela będzie znacznie mniejsza (ogólnie liczba stron danych potrzebnych silnikowi pamięci) niż gdybym utworzył moją kolumnę jako char (255). Za każdym razem, gdy wykonuję operację (DML) na tej tabeli i żądam wielu wierszy, będzie szybciej, gdy moja kolumna jest varchar, ponieważ nie muszę się ruszać po tych wszystkich „dodatkowych” miejscach na końcu. Przenieś, jak w przypadku, gdy SQL Server wykonuje wewnętrzne sortowania, takie jak podczas operacji oddzielania lub łączenia, lub jeśli wybiera scalanie podczas swojego planu zapytań itp.

Ale korzystanie z varchar wiąże się z pewnym nakładem. SQL Server musi używać dwubajtowego wskaźnika (narzutu), aby w każdym wierszu wiedzieć, ile bajtów ma w nim kolumna myColumn danego wiersza. Problemem nie są dodatkowe 2 bajty, to konieczność „dekodowania” długości danych w mojej kolumnie w każdym wierszu.

Z moich doświadczeń wynika, że ​​najbardziej sensowne jest używanie char zamiast varchar w kolumnach, do których będą dołączane zapytania. Na przykład klucz podstawowy tabeli lub inna kolumna, która będzie indeksowana. CustomerNumber w tabeli demograficznej lub CodeID w tabeli dekodowania, a może OrderNumber w tabeli zamówień. Używając char, silnik zapytań może szybciej wykonać łączenie, ponieważ może wykonywać arytmetykę prostych wskaźników (deterministycznie) zamiast przesuwać swoje wskaźniki o zmienną liczbę bajtów podczas odczytywania stron. Wiem, że mogłem cię zgubić w ostatnim zdaniu. Połączenia w SQL Server są oparte na idei „predykatów”. Predykat jest warunkiem. Na przykład myColumn = 1 lub OrderNumber <500.

Jeśli więc SQL Server wykonuje instrukcję DML, a predykaty lub łączone „klucze” mają stałą długość (char), silnik zapytań nie musi wykonywać tyle pracy, aby dopasować wiersze z jednej tabeli do wierszy od inny stół. Nie będzie musiał dowiedzieć się, jak długo dane znajdują się w wierszu, a następnie przejdź wzdłuż ciągu znaków, aby znaleźć koniec. Wszystko to wymaga czasu.

Teraz pamiętaj, że można to łatwo źle wdrożyć. Widziałem char używane do pól klucza podstawowego w systemach online. Szerokość musi być mała, tzn. Char (15) lub coś rozsądnego. I działa najlepiej w systemach online, ponieważ zwykle pobierasz lub wstawiasz tylko niewielką liczbę wierszy, więc konieczność „przycięcia” tych końcowych spacji, które otrzymasz w zestawie wyników, jest trywialnym zadaniem, a nie dołączaniem do milionów wiersze z jednej tabeli do milionów wierszy w innej tabeli.

Innym powodem, dla którego CHAR ma sens w porównaniu z varchar w systemach online, jest to, że zmniejsza podział stron. Używając char, zasadniczo „rezerwujesz” (i marnujesz) to miejsce, więc jeśli użytkownik przyjdzie później i umieści więcej danych w tej kolumnie, SQL już przydzielił dla niego miejsce i idzie.

Kolejny powód do użycia CHAR jest podobny do drugiego. Jeśli programista lub użytkownik wykona aktualizację „wsadową” do milionów wierszy, dodając na przykład jakieś zdanie do pola notatki, nie dostaniesz połączenia z DBA w środku nocy, zastanawiając się, dlaczego ich dyski są pełne. Innymi słowy, prowadzi to do bardziej przewidywalnego wzrostu wielkości bazy danych.

Są to 3 sposoby, w jakie system online (OLTP) może korzystać z char w porównaniu z varchar. Prawie nigdy nie używam char w scenariuszu hurtowni / analizy / OLAP, ponieważ zwykle masz tak dużo danych, że wszystkie te kolumny char mogą zsumować wiele zmarnowanego miejsca.

Należy pamiętać, że char może znacznie zwiększyć bazę danych, ale większość narzędzi do tworzenia kopii zapasowych ma kompresję danych, więc kopie zapasowe mają zwykle taki sam rozmiar, jak gdybyś używał varchar. Na przykład LiteSpeed ​​lub RedGate SQL Backup.

Innym zastosowaniem są widoki utworzone do eksportowania danych do pliku o stałej szerokości. Powiedzmy, że muszę wyeksportować niektóre dane do płaskiego pliku, aby mógł je odczytać komputer mainframe. Jest to stała szerokość (nie jest ograniczona). Lubię przechowywać dane w mojej tabeli „pomostowej” jako varchar (zużywając w ten sposób mniej miejsca w mojej bazie danych), a następnie używam widoku do CAST wszystkiego do wartości równoważnej char, o długości odpowiadającej szerokości stałej szerokości dla tej kolumny . Na przykład:

create table tblStagingTable (
pkID BIGINT (IDENTITY,1,1),
CustomerFirstName varchar(30),
CustomerLastName varchar(30),
CustomerCityStateZip varchar(100),
CustomerCurrentBalance money )

insert into tblStagingTable
(CustomerFirstName,CustomerLastName, CustomerCityStateZip) ('Joe','Blow','123 Main St Washington, MD 12345', 123.45)

create view vwStagingTable AS
SELECT CustomerFirstName = CAST(CustomerFirstName as CHAR(30)),
CustomerLastName = CAST(CustomerLastName as CHAR(30)),
CustomerCityStateZip = CAST(CustomerCityStateZip as CHAR(100)),
CustomerCurrentBalance = CAST(CAST(CustomerCurrentBalance as NUMERIC(9,2)) AS CHAR(10))

SELECT * from vwStagingTable

To jest fajne, ponieważ wewnętrznie moje dane zajmują mniej miejsca, ponieważ używają varchar. Ale kiedy używam DTS lub SSIS, a nawet po prostu wycinam i wklejam z SSMS do Notatnika, mogę korzystać z widoku i uzyskać odpowiednią liczbę końcowych spacji. W DTS mieliśmy funkcję o nazwie, cholera, zapomniałem, że myślę, że nazywała się „sugeruj kolumny” lub coś w tym rodzaju. W SSIS nie możesz już tego robić, musisz żmudnie zdefiniować menedżera połączeń plików płaskich. Ale ponieważ masz skonfigurowany widok, SSIS może znać szerokość każdej kolumny i może zaoszczędzić dużo czasu podczas budowania zadań przepływu danych.

Więc dolna linia ... użyj varchar. Istnieje bardzo mała liczba powodów, dla których warto użyć char i tylko z powodów wydajnościowych. Jeśli masz system z setkami milionów wierszy, zobaczysz zauważalną różnicę, jeśli predykaty są deterministyczne (char), ale dla większości systemów używających char po prostu marnuje miejsce.

Mam nadzieję, że to pomaga. Jeff

Jeff
źródło
Mówisz, że stały czat zajmuje więcej miejsca nie tylko podczas przechowywania, ale także podczas transportu lub „przenoszenia”, jak mówisz? Na przykład z serwera DB do mojego klienta? Kiedy tracimy te bajty zerowe?
The Red Pea
9

Są korzyści z wydajności, ale tutaj jest jedna, o której nie wspomniano: migracja wierszy. Dzięki char rezerwujesz z wyprzedzeniem całą przestrzeń, więc powiedzmy, że masz char (1000) i przechowujesz 10 znaków, zużyjesz wszystkie 1000 charaterów przestrzeni. W varchar2 (1000) użyjesz tylko 10 znaków. Problem pojawia się podczas modyfikowania danych. Załóżmy, że zaktualizowałeś kolumnę, aby teraz zawierała 900 znaków. Możliwe jest, że przestrzeń do rozwinięcia varchara nie będzie dostępna w bieżącym bloku. W takim przypadku silnik DB musi migrować wiersz do innego bloku i utworzyć wskaźnik w oryginalnym bloku do nowego wiersza w nowym bloku. Aby odczytać te dane, silnik DB będzie musiał teraz odczytać 2 bloki.
Nikt nie może jednoznacznie powiedzieć, że varchar lub char są lepsze. Jest miejsce na kompromis czasowy i rozważenie, czy dane zostaną zaktualizowane, zwłaszcza jeśli istnieje duża szansa, że ​​wzrosną.

Tony BenBrahim
źródło
Myślę, że masz literówkę w swoim poście - czy varchar2 (1000) nie powinien być CHAR (1000)?
Matt Rogish,
8

Istnieje różnica między wczesną optymalizacją wydajności a zastosowaniem reguły typu najlepszych praktyk. Jeśli tworzysz nowe tabele, w których zawsze będziesz mieć pole o stałej długości, warto użyć CHAR, w takim przypadku powinieneś go użyć. To nie jest wczesna optymalizacja, ale raczej wdrożenie praktycznej reguły (lub najlepszej praktyki).

tj. - Jeśli masz dwuliterowe pole stanu, użyj CHAR (2). Jeśli masz pole z rzeczywistymi nazwami stanów, użyj VARCHAR.

Bryan Rehbein
źródło
8

Wybrałbym varchar, chyba że kolumna przechowuje stałą wartość, taką jak kod stanu USA - który zawsze ma 2 znaki, a lista prawidłowych kodów stanów USA nie zmienia się często :).

W każdym innym przypadku, nawet jak przechowywanie zaszyfrowanego hasła (o stałej długości), wybrałbym varchar.

Dlaczego - kolumna typu char jest zawsze wypełniana spacjami, co powoduje, że kolumna my_column zdefiniowana jako char (5) z wartością „ABC” wewnątrz porównania:

my_column = 'ABC' -- my_column stores 'ABC  ' value which is different then 'ABC'

fałszywe.

Ta funkcja może prowadzić do wielu irytujących błędów podczas programowania i utrudnia testowanie.

Grzegorz Gierlik
źródło
1
Przynajmniej w MSSQL Server „abc” = „abc”. Nigdy się nie zastanawiałem, czy podoba mi się ta funkcja, czy jej nie
Mark Brackett,
Dobra lektura na temat wypełniania char tutaj Padding
Edward
6

CHAR zajmuje mniej miejsca niż VARCHAR, jeśli wszystkie wartości danych w tym polu są tej samej długości. Być może teraz w 2009 r. Baza danych o pojemności 800 GB jest taka sama pod każdym względem, jak 810 GB, jeśli przekształciłeś VARCHAR na CHAR, ale w przypadku krótkich ciągów (1 lub 2 znaków), CHAR jest nadal „najlepszą praktyką” w branży.

Teraz, gdy spojrzysz na szeroką gamę typów danych, które większość baz danych zapewnia nawet dla liczb całkowitych (bit, malutki, int, bigint), istnieją powody, aby wybrać jeden z nich. Po prostu wybranie biginta za każdym razem jest właściwie trochę nieświadome celów i zastosowań tej dziedziny. Jeśli pole po prostu reprezentuje wiek osoby w latach, bigint jest przesadą. Teraz niekoniecznie jest to „złe”, ale nie jest wydajne.

Ale to ciekawy argument, a ponieważ bazy danych poprawiają się z czasem, można argumentować, że CHAR vs VARCHAR staje się mniej istotny.

Scott Duffy
źródło
4

Opieram się na komentarzu Jima McKeetha.

Ponadto indeksowanie i pełne skanowanie tabeli są szybsze, jeśli tabela ma tylko kolumny CHAR. Zasadniczo optymalizator będzie w stanie przewidzieć, jak duży jest każdy rekord, jeśli ma tylko kolumny CHAR, podczas gdy musi sprawdzić wartość wielkości każdej kolumny VARCHAR.

Poza tym, jeśli zaktualizujesz kolumnę VARCHAR do rozmiaru większego niż jej poprzednia zawartość, możesz zmusić bazę danych do odbudowania jej indeksów (ponieważ zmusiłeś bazę danych do fizycznego przeniesienia rekordu na dysk). Podczas gdy z kolumnami CHAR nigdy się to nie wydarzy.

Ale prawdopodobnie nie zależy ci na wydajności, chyba że Twój stół jest ogromny.

Pamiętajcie o mądrych słowach Djikstry. Wczesna optymalizacja wydajności jest źródłem wszelkiego zła.

Alvaro Rodriguez
źródło
4
W twoim komentarzu jest pewien stopień spekulacji. Widziałem raz po raz takie założenia, jak te, które są testowane i okazuje się, że jest dokładnie odwrotnie. Problem polega na tym, że wielu inżynierów bierze takie informacje za ewangelię. Proszę, stwórz przypadki testowe, które odzwierciedlają twoje prawdziwe sytuacje.
Ethan Post
Ethan ma całkowitą rację. Zależy to więc od implementacji, której używasz bez odniesień do faktycznego (produktu, wersji), jest to całkowicie bezużyteczne.
David Schmitt
Podczas aktualizacji CHARkolumny indeksy również muszą zostać zaktualizowane. Pod tym względem nie ma różnicy w aktualizacji kolumny VARCHAR lub CHAR. Pomyśl o aktualizacji FOOdo BAR.
a_horse_w_no_name
4

Wiele osób zauważyło, że jeśli znasz dokładną długość wartości, użycie CHAR ma pewne zalety. Ale mimo że przechowywanie stanów USA jako CHAR (2) jest dziś świetne, kiedy otrzymujesz wiadomość ze sprzedaży, że „Właśnie dokonaliśmy naszej pierwszej sprzedaży do Australii”, jesteś w świecie bólu. Zawsze przesyłam, aby przecenić, jak długo, jak sądzę, pola będą musiały być, zamiast „dokładnego” przypuszczenia, by pokryć przyszłe wydarzenia. VARCHAR zapewni mi większą elastyczność w tym obszarze.

Craig
źródło
3

Myślę, że w twoim przypadku prawdopodobnie nie ma powodu, aby nie wybierać Varchara. Daje to elastyczność i, jak już wspomniano wielu respondentów, wydajność jest teraz taka, że ​​oprócz bardzo szczególnych okoliczności, my, śmiertelnicy (w przeciwieństwie do Google DBA) nie zauważymy różnicy.

Interesującą rzeczą wartą odnotowania, jeśli chodzi o typy DB, jest sqlite (popularna mini baza danych o dość imponującej wydajności) umieszczająca wszystko w bazie danych jako ciąg i typy w locie.

Zawsze używam VarChar i zwykle robię to znacznie większym, niż mógłbym potrzebować. Na przykład. 50 za imię, jak mówisz, dlaczego nie po prostu być bezpiecznym.

Toby Allen
źródło
3

NIGDY nie używałbym znaków. Dyskutowałem z wieloma osobami i zawsze przywołują zmęczone stereotypy, że char jest szybszy. Cóż, mówię, o ile szybciej? O czym tu mówimy, milisekundach, sekundach, a jeśli tak, ile? Mówisz mi, bo ktoś twierdzi, że to kilka milisekund szybciej, czy powinniśmy wprowadzić mnóstwo trudnych do naprawienia błędów w systemie?

Oto kilka problemów, na które napotkasz:

Każde pole zostanie uzupełnione, więc na zawsze otrzymasz kod, który ma wszędzie RTRIMS. Jest to również ogromne marnotrawstwo miejsca na dysku dla dłuższych pól.

Powiedzmy, że masz kwintesencję przykładu pola znakowego złożonego tylko z jednej postaci, ale pole jest opcjonalne. Jeśli ktoś przekazuje pusty ciąg do tego pola, staje się on jedną spacją. Gdy więc inna aplikacja / proces zapyta go, otrzymają jedną spację, jeśli nie używają rtrim. Mamy dokumenty XML, pliki i inne programy, wyświetlamy tylko jedno miejsce, w opcjonalnych polach i psujemy rzeczy.

Więc teraz musisz upewnić się, że przekazujesz wartości null, a nie pusty ciąg znaków, do pola char. Ale to NIE jest prawidłowe użycie wartości null. Oto użycie wartości null. Powiedzmy, że otrzymujesz plik od dostawcy

Imię | Płeć | Miasto

Bob || Los Angeles

Jeśli płeć nie jest określona, ​​wpisz Bob, pusty ciąg i Los Angeles do tabeli. Powiedzmy teraz, że otrzymujesz plik i jego zmiany formatu, a płeć nie jest już uwzględniona, ale była w przeszłości.

Nazwa | Miasto

Bob | Seattle

Teraz, ponieważ płeć nie jest uwzględniona, użyłbym null. Varchars obsługują to bez problemów.

Z drugiej strony Char jest inny. Zawsze musisz wysłać zero. Jeśli kiedykolwiek wyślesz pusty ciąg, skończysz z polem zawierającym spacje.

Mógłbym bez końca ze wszystkimi błędami, które musiałem naprawić z postaci i przez około 20 lat rozwoju.

Mauro Torres
źródło
2

Przy obliczaniu rzeczywistej potrzebnej wielkości wartości kolumny i przydzielaniu miejsca dla Varchara istnieje pewien niewielki narzut związany z przetwarzaniem, więc jeśli masz pewność, jak długo ta wartość będzie zawsze, lepiej użyć Char i uniknąć trafienia.

Guy Starbuck
źródło
2

To klasyczna przestrzeń kontra wydajność.

W MS SQL 2005 Varchar (lub NVarchar dla sieci wymagających dwóch bajtów na znak, tj. Chiński) ma zmienną długość. Jeśli dodasz do wiersza po zapisaniu go na dysku twardym, zlokalizuje on dane w niezainteresowanym miejscu do oryginalnego wiersza i doprowadzi do fragmentacji plików danych. Wpłynie to na wydajność.

Tak więc, jeśli przestrzeń nie jest problemem, Char jest lepszy pod względem wydajności, ale jeśli chcesz zmniejszyć rozmiar bazy danych, lepiej są varchary.

Leo Moore
źródło
2

Podział. Char rezerwuje miejsce, a VarChar nie. Podział strony może być wymagany w celu dostosowania aktualizacji do varchar.

paparazzo
źródło
Z powodu wielu innych czynników podczas aktualizacji CHARkolumny może dojść do podziału strony .
Rick James
1

podczas używania wartości varchar SQL Server potrzebuje dodatkowych 2 bajtów na wiersz do przechowywania niektórych informacji o tej kolumnie, natomiast jeśli używasz char, nie potrzebuje tego, chyba że

SQLMenace
źródło
0

W niektórych bazach danych SQL VARCHAR zostanie uzupełniony do maksymalnego rozmiaru w celu zoptymalizowania przesunięć. Jest to przyspieszenie pełnego skanowania tabel i indeksów.

Z tego powodu nie masz żadnych oszczędności miejsca dzięki użyciu VARCHAR (200) w porównaniu do CHAR (200)

FlySwat
źródło
3
Które bazy danych implementują VARCHAR w ten sposób?
Troels Arvin,
5
Poważnie, jaka baza danych implementuje to w ten sposób? To, co opisujesz, dotyczy zwykle CHAR, a nie VARCHAR.
Richard Simões
mysql skonwertuje varchar na znaki, jeśli w tej samej tabeli są znaki char i varchar.
Malfist
Moją interpretacją komentarzy MySQL jest to, że nie dotyczy to podstawowej tabeli pamięci, ale może być odpowiednie dla tabel tymczasowych, np. do grupowania / sortowania danych. dev.mysql.com/doc/refman/8.0/en/char.html stackoverflow.com/questions/262238/…
Thomas W
0

Korzystanie z CHAR (NCHAR) i VARCHAR (NVARCHAR) wprowadza różnice w sposobie przechowywania danych przez serwer bazy danych. Pierwszy wprowadza spacje końcowe; Wystąpił problem podczas używania go z operatorem LIKE w funkcjach SQL SERVER. Muszę więc zapewnić bezpieczeństwo, używając VARCHAR (NVARCHAR) przez cały czas.

Na przykład, jeśli mamy tabelę TEST (ID INT, Status CHAR (1)) , a ty piszesz funkcję, aby wyświetlić listę wszystkich rekordów o określonej wartości, takich jak:

CREATE FUNCTION List(@Status AS CHAR(1) = '')
RETURNS TABLE
AS
RETURN
SELECT * FROM TEST
WHERE Status LIKE '%' + @Status '%'

W tej funkcji oczekujemy, że po wstawieniu parametru domyślnego funkcja zwróci wszystkie wiersze, ale w rzeczywistości tak nie jest. Zmień typ danych @Status na VARCHAR naprawi problem.

Tuan Le PN
źródło
Można to również zmienić przez ansi_padding Jak pobierane są wartości
Edward