Poprawnie – dla kolumny z kodami pocztowymi najlepszym wyborem jest typ CHAR. Kody pocztowe są danymi tekstowymi, a nie liczbowymi, mimo że często składają się wyłącznie z cyfr. W wielu krajach (np. w Polsce, Wielkiej Brytanii czy Kanadzie) kod pocztowy może zawierać myślniki, spacje, a nawet litery. Co ważne, długość kodu jest z góry znana i stała (np. w Polsce zawsze 6 znaków w formacie „NN-NNN”). Typ CHAR został właśnie zaprojektowany do przechowywania krótkich łańcuchów znaków o stałej długości. Silnik bazy danych rezerwuje stałą ilość miejsca i dopełnia wartość spacjami, jeśli jest krótsza. Dzięki temu porównywanie, indeksowanie i sortowanie takich pól jest przewidywalne i wydajne. Moim zdaniem jest to dokładnie ten przypadek, który się podręcznikowo podaje na zajęciach: PESEL, NIP, numer dokumentu, kod pocztowy – wszystkie to typowe przykłady na CHAR. W praktyce np. w MySQL zdefiniujesz taką kolumnę jako CHAR(6), w PostgreSQL jako CHAR(6) albo ewentualnie VARCHAR(6), ale przy stałej długości CHAR jest bardziej jednoznacznym sygnałem projektowym. Dodatkowo użycie typu znakowego zapobiega „obcinaniu” zer wiodących, co jest częstym błędem przy traktowaniu kodów pocztowych jako liczby. W wielu systemach legacy właśnie z tego powodu trzeba było później migrować typ danych z numerycznego na tekstowy. Z punktu widzenia dobrych praktyk modelowania danych przyjmuje się zasadę: jeżeli coś nie służy do liczenia, tylko jest identyfikatorem lub etykietą, to przechowujemy to jako tekst, a dla stałej długości – jako CHAR o odpowiednim rozmiarze.
Przy typie danych dla kodów pocztowych łatwo wpaść w pułapkę myślenia „składa się z cyfr, więc to liczba”. To jeden z częstszych błędów przy projektowaniu schematów baz danych. Kod pocztowy jest w rzeczywistości identyfikatorem tekstowym, a nie wartością numeryczną do obliczeń. Dlatego wybór typów takich jak TEXT, BLOB czy DECIMAL prowadzi do różnych problemów logicznych i wydajnościowych. Duży typ tekstowy, taki jak TEXT, jest przeznaczony do przechowywania dłuższych opisów, komentarzy, treści artykułów i innych pól o zmiennej, zazwyczaj nieograniczonej długości. Silnik bazy danych zwykle przechowuje te dane poza główną strukturą rekordu, co ma sens dla długich stringów, ale dla krótkiego kodu pocztowego jest po prostu przerostem formy nad treścią. Tracisz też jasną informację, że długość powinna być stała, trudniej jest narzucić sensowne ograniczenia, a indeksowanie takich pól bywa mniej efektywne. Jeszcze mniej pasuje BLOB, który służy do binarnych danych, takich jak obrazy, pliki PDF, dane multimedialne. Traktowanie kodu pocztowego jako ciągu bajtów bez kontekstu znakowego kompletnie mija się z celem. Taki typ utrudnia sortowanie, filtrowanie, walidację formatu i w zasadzie odcina cię od naturalnych mechanizmów operowania na tekstach, jakie oferuje SQL. DECIMAL wygląda pozornie kusząco, bo „kod to cyfry”, ale tutaj właśnie leży klasyczny błąd. Typy numeryczne są projektowane do obliczeń matematycznych, a nie do identyfikatorów. Możesz wtedy stracić zera wiodące, co w kodach pocztowych ma krytyczne znaczenie. Dodatkowo w wielu krajach kody zawierają litery czy myślniki, więc DECIMAL po prostu nie pozwoli na poprawne zapisanie takich wartości. Z mojego doświadczenia, gdy ktoś wybiera typ liczbowy dla kodu pocztowego, potem i tak musi migrować schemat, bo pojawiają się nowe wymagania, inne formaty, integracja z zagranicznymi systemami. W dobrze zaprojektowanych modelach danych przyjmuje się zasadę: identyfikatory i kody, które nie służą do liczenia, przechowujemy jako tekst o kontrolowanej długości. W tym wypadku idealnie pasuje CHAR o odpowiednim rozmiarze, bo jasno komunikuje, że długość jest stała i pozwala silnikowi bazy optymalizować przechowywanie oraz indeksy. Wybór innego typu zwykle wynika z mylenia „cyfr” z „liczbami”, co na etapie projektowania wydaje się drobiazgiem, a później odbija się na jakości całego systemu.