Powrót do strony głównej

Typy danych dla paszportu i identyfikatorów w SQL: błędy przechowywania

Artykuł wyjaśnia, dlaczego do przechowywania numerów paszportów i innych identyfikatorów w bazach SQL należy używać typów danych łańcuchowych, a nie numerycznych. Omówiono semantykę danych, problem wiodących zer i praktyczne przykłady błędów. Przedstawiono tabelę poprawnych typów dla rosyjskich identyfikatorów.

Paszport w bazie danych: dlaczego VARCHAR, a nie INTEGER
Advertisement 728x90

Typy danych dla identyfikatorów: dlaczego paszport to nie liczba

Proste pytanie o wybór typu danych do przechowywania numeru paszportu w bazie SQL dzieli programistów na tych, którzy myślą o semantyce danych, i tych, którzy działają szablonowo. Błąd w wyborze INTEGER zamiast VARCHAR może prowadzić do utraty zer wiodących i uszkodzonej identyfikacji, co jest krytyczne dla systemów z milionami użytkowników. Ten artykuł omawia fundamentalną zasadę projektowania schematów danych, opartą na naturze informacji, a nie jej wyglądzie.

Semantyka danych a ich forma

Większość programistów na rozmowach kwalifikacyjnych, widząc cyfry w numerze paszportu, automatycznie wybiera typy numeryczne, takie jak INTEGER lub BIGINT. To klasyczny błąd spowodowany powierzchowną analizą. Kluczowe pytanie nie dotyczy tego, z czego składają się dane, ale jak są używane. Z serią i numerem paszportu nigdy nie wykonuje się operacji arytmetycznych — tylko porównuje się je pod kątem równości, wyszukuje i przesyła. To identyfikatory, a nie wartości. Dlatego prawidłowy typ to ciąg znaków: CHAR(4) dla serii i CHAR(6) dla numeru, lub CHAR(10) dla połączonej wartości. Przechowywanie w INTEGER prowadzi do nieodwracalnej utraty zer wiodących: wartość 0306 zamienia się w 306, czyniąc dokument nieważnym bez żadnych błędów w logach.

Praktyczne konsekwencje błędu

Błąd w wyborze typu danych nie jest teoretyczny — regularnie występuje w produkcji. Na przykład, w serwisie do rejestracji abonamentów parkingowych pole paszportu typu NUMBER cicho przycinało zero wiodące, co doprowadziło do niezgodności danych w bazie i na papierze. Incydent przeszedł niezauważony przez przegląd kodu i testowanie, aż dotknął użytkowników z seriami paszportów zaczynającymi się od zera. W Rosji są miliony takich dokumentów, co zwiększa skalę problemu. Argumenty dotyczące optymalizacji, takie jak oszczędność miejsca lub szybkość indeksów, są tutaj nieuzasadnione:

Google AdInline article slot
  • CHAR(4) zajmuje te same 4 bajty, co INTEGER dla cyfr w kodowaniu jednobajtowym.
  • Indeksy na VARCHAR działają z efektywnością O(log n), podobnie jak numeryczne, a różnica w wydajności dla stałych ciągów jest znikoma.

Oszczędność bajtów nie usprawiedliwia ryzyka utraty danych.

Rozszerzenie zasady na inne identyfikatory

Zasada „jeśli nie wykonuje się arytmetyki na danych — to nie jest liczba” ma zastosowanie do wielu identyfikatorów w rosyjskich i międzynarodowych systemach. Rozważmy główne przykłady:

  • SNILS (11 cyfr, format XXX-XXX-XXX XX): przechowywać jako VARCHAR(14) lub CHAR(11) po usunięciu myślników, a nie BIGINT.
  • INN osoby fizycznej (12 cyfr): może zaczynać się od zera dla regionów 01–09, więc VARCHAR(12) jest obowiązkowe.
  • Numer telefonu: tylko VARCHAR(20), aby zachować format z '+' dla numerów międzynarodowych.
  • Kod pocztowy: CHAR(6), ponieważ międzynarodowe kody mogą być alfanumeryczne.
  • Konto bankowe (20 cyfr): CHAR(20), ponieważ typy numeryczne nie obsługują takich długości bez przepełnienia.

Używanie typów ciągów znaków zapewnia elastyczność i zapobiega utracie danych przy zmianie formatów.

Google AdInline article slot

Co jest ważne

  • Semantyka jest priorytetem: wybieraj typ danych na podstawie operacji na nich, a nie wyglądu.
  • Zera wiodące są krytyczne: typy numeryczne je przycinają, niszcząc identyfikację dla milionów dokumentów.
  • Optymalizacja jest drugorzędna: oszczędność bajtów lub mikrosekund nie jest warta ryzyka nieprawidłowych danych.
  • Zasada jest uniwersalna: ma zastosowanie do SNILS, INN, telefonów i innych identyfikatorów.
  • Sprawdzaj schematy: audyt istniejących baz może ujawnić ukryte luki.

Metodyka wyboru typu danych

Dobry inżynier przy projektowaniu pola w bazie danych zadaje trzy pytania:

  • Jaka jest semantyka tych danych? (np. identyfikator, wartość, tekst).
  • Jakie operacje będą wykonywane? (porównanie, wyszukiwanie, arytmetyka).
  • Jakie ograniczenia nakłada dziedzina? (format, długość, dozwolone znaki).

Odpowiedzi określają wybór: dla identyfikatorów — typy ciągów, dla wartości — numeryczne. To podejście odróżnia rozwiązywanie problemów od mechanicznego pisania kodu i zapobiega kosztownym błędom na wczesnych etapach.

Tabela typów dla rosyjskich identyfikatorów

| Dane | Format | Prawidłowy typ | Częsty błąd | Konsekwencje błędu |

Google AdInline article slot

|--------|--------|----------------|---------------|---------------------|

| Seria paszportu | 4 cyfry | CHAR(4) | INTEGER | Utrata zera wiodącego, nieważny dokument |

| Numer paszportu | 6 cyfr | CHAR(6) | INTEGER | Przycięcie zera, uszkodzona identyfikacja |

| Paszport (pełny) | 10 cyfr | CHAR(10) | BIGINT | Utrata do dwóch zer wiodących |

| SNILS | 11 cyfr | CHAR(11) | BIGINT | Przycięcie dla kodów 01–09 |

| INN osoby fizycznej | 12 cyfr | CHAR(12) | BIGINT | Utrata cyfry przy kodzie 01–09 |

| Telefon | +7... | VARCHAR(20) | BIGINT | Niemożność przechowywania '+', niezgodność z formatami międzynarodowymi |

| Kod pocztowy | 6 cyfr | CHAR(6) | INTEGER | Brak wsparcia dla alfanumerycznych kodów międzynarodowych |

| Konto bankowe | 20 cyfr | CHAR(20) | Brak odpowiedniego INT | Przepełnienie, ryzyko błędów finansowych |

Ta tabela służy jako ściągawka do projektowania i audytu schematów baz danych.

— Editorial Team

Advertisement 728x90

Czytaj dalej