Typy dat pro identifikátory: Proč číslo pasu není číslo
Jednoduchá otázka ohledně volby datového typu pro ukládání čísla pasu v SQL databázi rozděluje vývojáře na ty, kteří přemýšlejí o sémantice dat, a na ty, kteří jednají podle šablony. Chyba ve volbě INTEGER místo VARCHAR může vést ke ztrátě úvodních nul a porušené identifikaci, což je kritické pro systémy s miliony uživatelů. Tento článek rozebírá základní princip návrhu datových schémat, založený na povaze informace, nikoli na jejím vzhledu.
Sémantika dat versus jejich forma
Většina vývojářů na pohovorech, když vidí číslice v čísle pasu, automaticky volí číselné typy, jako je INTEGER nebo BIGINT. Toto je klasická chyba způsobená povrchní analýzou. Klíčová otázka nespočívá v tom, z čeho se data skládají, ale v tom, jak se používají. S číslem pasu se nikdy neprovádějí aritmetické operace – pouze se porovnává na rovnost, hledá a přenáší. Jde o identifikátory, nikoli o veličiny. Proto správný typ je řetězcový: CHAR(4) pro sérii a CHAR(6) pro číslo, nebo CHAR(10) pro spojenou hodnotu. Ukládání v INTEGER vede k nevratné ztrátě úvodních nul: hodnota 0306 se změní na 306, což činí dokument neplatným bez jakýchkoli chyb v logech.
Praktické důsledky chyby
Chyba ve volbě datového typu není teoretická – pravidelně se vyskytuje v produkci. Například v službě pro vydávání parkovacích předplatných pole pro pas typu NUMBER tiše odstranilo úvodní nulu, což vedlo k nesouladu mezi daty v databázi a na papíře. Incident prošel bez povšimnutí přes kontrolu kódu a testování, dokud nepostihl uživatele s pasy začínajícími nulou. V Česku existují tisíce takových dokumentů, což problém zesiluje. Argumenty o optimalizaci, jako je úspora místa nebo rychlost indexů, zde neobstojí:
- CHAR(4) zabírá stejné 4 bajty jako INTEGER pro číslice v jednobajtovém kódování.
- Indexy na VARCHAR pracují s efektivitou O(log n), podobně jako číselné, a rozdíl ve výkonu pro pevné řetězce je zanedbatelný.
Úspora bajtů neospravedlňuje riziko ztráty dat.
Rozšíření principu na další identifikátory
Pravidlo „pokud nad daty neprovádíte aritmetiku – nejde o číslo“ platí pro mnoho identifikátorů v českých a mezinárodních systémech. Podívejme se na hlavní příklady:
- Rodné číslo (10 znaků, formát YYMMDD/XXXX): ukládat jako CHAR(11) včetně lomítka, ne BIGINT.
- Daňové identifikační číslo (DIČ) (řetězec, např. CZ12345678): VARCHAR(20) je nutné, protože může obsahovat písmena.
- Telefonní číslo: pouze VARCHAR(20), aby se zachoval formát s '+' pro mezinárodní čísla.
- Poštovní směrovací číslo: VARCHAR(10), protože mezinárodní kódy mohou být alfanumerické.
- Bankovní účet (až 20 číslic): CHAR(20), protože číselné typy nepodporují takové délky bez přetečení.
Použití řetězcových typů zajišťuje flexibilitu a zabraňuje ztrátě dat při změnách formátů.
Co je důležité
- Sémantika je primární: volte datový typ na základě operací s daty, ne podle vzhledu.
- Úvodní nuly jsou kritické: číselné typy je odstraní, což naruší identifikaci u tisíců dokumentů.
- Optimalizace je sekundární: úspora bajtů nebo mikrosekund nestojí za riziko nesprávných dat.
- Princip je univerzální: platí pro rodné číslo, DIČ, telefony a další identifikátory.
- Kontrolujte schémata: audit stávajících databází může odhalit skryté zranitelnosti.
Metodika volby datového typu
Dobrý inženýr při návrhu pole v databázi si položí tři otázky:
- Jaká je sémantika těchto dat? (např. identifikátor, veličina, text).
- Jaké operace budou prováděny? (porovnání, vyhledávání, aritmetika).
- Jaká omezení ukládá předmětná oblast? (formát, délka, povolené znaky).
Odpovědi určují volbu: pro identifikátory – řetězcové typy, pro veličiny – číselné. Tento přístup odlišuje řešení problémů od mechanického psaní kódu a předchází nákladným chybám v raných fázích.
Tabulka typů pro české identifikátory
| Data | Formát | Správný typ | Častá chyba | Důsledky chyby |
|------|--------|-------------|-------------|----------------|
| Číslo pasu | Řetězec (např. 10 číslic) | CHAR(10) nebo VARCHAR(20) | INTEGER | Ztráta úvodních nul, neplatný dokument |
| Rodné číslo | YYMMDD/XXXX (10 znaků) | CHAR(11) | BIGINT | Nesprávné ukládání, porušení formátu |
| Daňové identifikační číslo (DIČ) | Řetězec (např. CZ12345678) | VARCHAR(20) | INTEGER | Nemožnost ukládání písmen, chyby v identifikaci |
| Telefonní číslo | +420... | VARCHAR(20) | BIGINT | Ztráta '+', nekompatibilita s mezinárodními formáty |
| Poštovní směrovací číslo | 6 číslic nebo alfanumerické | VARCHAR(10) | INTEGER | Nepodpora mezinárodních formátů |
| Bankovní účet | Až 20 číslic | CHAR(20) | Žádný vhodný INT | Přetečení, riziko finančních chyb |
Tato tabulka slouží jako pomůcka pro návrh a audit databázových schémat.
— Editorial Team
Zatím žádné komentáře.