Heronovo IT doupě

Používejte správné datové typy

Poznámka o datových typech a SQL.

Po zprovoznění IPv6, či lépe řečeno přepnutí z dlouhodobého nestabilního testovacího stavu do (doufejme) již stabilního ostrého, jsem i tomuto svému blogu přiřadil také AAAA záznam (takže pokud máte funkční připojení přes IPv6, právě čtete tyto stránky pomocí šestky).

Měl jsem tu také nasazený plugin Counterize pro statistiky přístupů. Chtěl jsem zjistit, kolik lidí sem přes šestku chodí.

Novou IP adresu jsem skutečně našel a to v podobě 2a02:7a00:4:11:e což je i pro nějakou zkrácenou formu nemyslné (samostatné :e znamená 000e, přičemž v adrese je ec06). Ořezání na 16 znaků dávalo tušit cosi nekalého.

A opravdu. Sloupec v tabulce statistik je definován jako `IP` varchar(16) NOT NULL.

Všechno špatně. IP adresa je číslo, nikoliv řetězec. IPv4 je 32b číslo, IPv6 je 128b číslo. Lze k tomu přidat i masku podsítě. IP adresy jako čísla lze snadno řadit (zkuste si to s řetězcem), a dělat s ní bitové operace (to už s řetězcem neuděláte), tak jak to dělají routery. Dalším důvodem jsou nároky na úložný prostor. Zatímco VARCHAR(16) bude mít v plné ASCII palbě 17B, tak 32b číslo 4B (nebo pokud to už chceme mít úplně košér a použijeme na to odpovídající datový typ tak 7B). Vynásobte si to očekávaným počtem záznamů v tabulce. U IPv6 by to bylo 44B vs. 16B (reps. 19B u typu inet). A to nemluvím o indexech.

Pozn: Kdyby ten plugin vůbec neuměl zpracovat návštěvy přicházející po IPv6, tak by mi to nevadilo. Vadí mi, že s IP adresami nakládá nevhodným způsobem a s ipv6 zcela špatně (všechny návštěvy z nesmyslné adresy 2a02:7a00:4:11:e spadnou do jednoho chlívku ve statistice).

Pokud by daný program použil odpovídající datový typ (v PostgreSQL inet), tak by jednak mohl využít všech funkcí, ale také by byl (alespoň částečně) připraven i na nový typ ip adres a nebylo by třeba upravovat schema.