it-swarm-eu.dev

Ukládání IP adresy

Musím uložit IP adresu všech registrovaných uživatelů do databáze. Zajímalo by mě, kolik znaků bych měl pro takový sloupec uvést?

Měl bych také podporovat IPv6? Pokud ano, jaká je maximální délka adresy IP?

26
Cleankod

Neskladujte jako řetězec. Použijte sloupec int unsigned A uložte/načtěte pomocí INET_ATON() a INET_NTOA(). AFAIK mysql nepodporuje INET_ * pro ipv6.

UPRAVIT podle komentáře

Použití vestavěné funkce pro převod IP na/z celých čísel (a tak uložení těchto celých čísel v databázi) má vedlejší účinek, který tyto IP adresy automaticky ověřuje. Řekněme, že ukládáte IP jako VARCHAR (16), musíte se ujistit, že neukládáte neplatné IP (jako příklad 999.999.999.999) s nějakou vlastní validací. O to se postarají funkce INET_ *.

27
Mr Shunz

Navrhl bych přechod na PostgreSQL a použití INET nebo CIDR datových typů.

CREATE TABLE test ( test_id serial PRIMARY KEY, address inet );
INSERT INTO test ( address ) VALUES ( '1.2.3.4'::inet );
INSERT INTO test ( address ) VALUES ( 'a:b::c:d'::inet );
SELECT * FROM test;
 test_id | address  
---------+----------
       1 | 1.2.3.4
       2 | a:b::c:d
7
jkj

Je pravděpodobně čas začít uvažovat o IPv6. MySQL nemá metody pro převod IPv6 adres do binárního formátu. Čtyřicet řetězců znaků zvládne všechny běžné adresy IPv6. Existuje formát, který by mohl přesáhnout 40 znaků, považuji ty, u kterých je nepravděpodobné, že by se vyskytly.

Můžete vypočítat velikost z té informace, že bude maximálně 8 čtyř skupin znaků se 7 oddělovači znaků. Neobvyklý formát nahrazuje poslední dvě skupiny adresou ve formátu IPv4. Bez komprese adresy nahradí posledních 9 znaků až 15 znaky.

Pokud ukládáte bloky, může označení velikosti bloku trvat 4 znaky, nikoli 3 znaky vyžadované pro IPv4.

Měli byste zajistit, aby vaše formátování bylo konzistentní, ale veškerý software, který jsem viděl, poskytuje konzistentní formáty pro adresy.

6
BillThor

Zde je nejlepší odpověď v jednom z e-mailových konferencí MySQL. Číst Nejlepší typ pole pro uložení IP adresy ... .

Stručně to navrhuje, který jsem za sekundu, použít INT (10) UNSIGNED.

  1. Využívá méně paměti (pouze 4 bajty)
  2. Nejvhodnější pro třídění a vyhledávání rozsahů IP, zejména pokud hledáte zemi původu svých návštěvníků.

Takže pomocí 192.168.10.50:

(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (výsledky v 192.168,10,50)

V MySQL můžete přímo použít SELECT INET_ATON('192.168.10.50'); a získat 3232238130.

Nebo

192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (zpět, výsledky v 50.10.168.192)

V MySQL můžete přímo použít SELECT INET_NTOA(3232238130); a získat 192.168.10.50 Zpět.

4
Eye

Od MySQL v5.6.3 přidali podporu pro INET6_ATON A INET6_NOTA, Které se budou starat o adresy IPv4 a IPv6. Ale už to neukládají jako celé číslo. IPv6 vrací varbinary(16) a IPv4 vrací varbinary(4).

http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-aton

2
Vizjerai

Můžete uložit až 15 znaků. Nepoužívejte prosím VARCHAR (15), protože to je 16 bajtů (první bajt spravuje délku řetězce a tím pomalejší načítání a ukládání). Používejte CHAR (15) vždy na něčem, jako je IP adresa.

1
RolandoMySQLDBA

Omlouváme se, ale nemůžu komentovat odpovědi. Na stackoverflow je otázka o tom . A naprosto souhlasím s vybranou odpovědí: použití 2xBIGINT je pravděpodobně nejlepší způsob, jak pro ipv6 v současné době.

Navrhoval bych jít na 2 * BIGINT, ale ujistěte se, že jsou NEPŘIPOJENÉ. Na hranici adresy/64 v IPv6 existuje určitý druh přirozeného rozdělení (protože a/64 je nejmenší velikost netblocku), která by s tím byla pěkně zarovnána.

Je také možné ukládat ipv4 do těchto bigints - buď označením jedné z nich NULL, nebo pomocí formátu V4COMPAT

0
rvs