Memorizzazione dell'indirizzo IP


25

Devo memorizzare l'indirizzo IP di tutti gli utenti registrati nel database. Mi chiedo, quanti personaggi dovrei dichiarare per una tale colonna?

Devo supportare anche IPv6? In tal caso, qual è la lunghezza massima dell'indirizzo IP?

Risposte:


27

Non archiviare come stringa. Utilizzare una int unsignedcolonna e archiviare / recuperare con INET_ATON()e INET_NTOA()rispettivamente. AFAIK mysql non supporta INET_ * per ipv6.

MODIFICA come da commento

L'uso della funzione integrata per convertire gli IP in / da numeri interi (e quindi la memorizzazione di tali numeri interi nel database) ha l'effetto collaterale di convalidare automaticamente tali IP. Supponi di archiviare un IP come VARCHAR (16), devi assicurarti di non archiviare IP non validi (come 999.999.999.999 come esempio) con una convalida personalizzata. Le funzioni INET_ * se ne occupano.


1
-1, gli indirizzi IP sono fino a 128 bit e il tipo intero più grande supportato da MySQL è 64 bit.
Hendrik Brummermann,

3
IPv4 è a 32 bit. 128 bit è per IPv6, che, come accennato, la roba INET_ * non supporta.
Richard,

1
Per l'indirizzo IPv6, utilizza le funzioni INET6_ATON () e INET6_NTOA (), vedi esempio - rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
rathishDBA

6

È probabilmente il momento di iniziare a considerare IPv6. MySQL non ha metodi per convertire gli indirizzi IPv6 in formato binario. Una stringa di quaranta caratteri gestirà tutti gli indirizzi IPv6 normali. Esiste un formato che potrebbe superare i 40 caratteri, considererei quelli che difficilmente potrebbero verificarsi.

È possibile calcolare la dimensione da allora informazioni che ci saranno al massimo 8 quattro gruppi di caratteri con 7 caratteri di separazione. Il formato anomalo sostituisce gli ultimi due gruppi con un indirizzo in formato IPv4. Senza compressione dell'indirizzo sostituisce gli ultimi 9 caratteri con un massimo di 15 caratteri.

Se si memorizzano blocchi, l'indicazione della dimensione del blocco può contenere 4 caratteri anziché i 3 caratteri richiesti per IPv4.

Dovresti assicurarti che la formattazione che ottieni sia coerente, ma tutto il software che ho visto offre formati coerenti per gli indirizzi.


2
Sono totalmente d'accordo, IPv6 sta arrivando ed è meglio essere pronti a farlo piuttosto che aspettarlo come Y2K: D
Jeff

Non solo sto arrivando, ma già qui sui miei sistemi.
BillThor,

6

Suggerirei la migrazione a PostgreSQL e l'uso di tipi di dati INET o CIDR .

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

Per ottenere quali IP sono presenti in una rete SELEZIONA * DA test DOVE indirizzo << '1.2.3.0/24'::inet;
jkj

4

Ecco la migliore risposta fatta in una delle mailing list di MySQL. Leggi migliore FieldType per memorizzare l'indirizzo IP in corso ... .

In breve suggerisce, che io secondo, di usare INT (10) UNSIGNED.

  1. Utilizza meno memoria (solo 4 byte)
  2. Ideale per l'ordinamento e la ricerca degli intervalli IP, soprattutto se cerchi il paese di origine dei tuoi visitatori.

Quindi, usando 192.168.10.50:

(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (risultati in 192.168.10.50)

In MySQL, puoi usare direttamente SELECT INET_ATON('192.168.10.50'); per ottenere 3232238130.

O

192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (Indietro, risultati in 50.10.168.192)

In MySQL, è possibile utilizzare direttamente SELECT INET_NTOA(3232238130); per tornare 192.168.10.50indietro.


Impressionante, +1 per te !!! L'utilizzo di 4 byte senza segno batte sicuramente la manipolazione delle stringhe ogni giorno.
RolandoMySQLDBA

-1, gli indirizzi IP sono fino a 128 bit e il tipo intero più grande supportato da MySQL è 64 bit.
Hendrik Brummermann,

3
nhnb, IPv6 è a 128 bit, ma la conversazione riguarda IPv4 che è a 32 bit. Non c'è bisogno di commentare ogni commento / risposta insistendo sulla tua conoscenza.
Occhio

La tua risposta non menziona il fatto che riguarda solo il vecchio protocollo Internet, mentre la domanda menziona esplicitamente IPv6 alla fine. Dato che l'ultimo provider Internet sindaco (almeno nel mio paese) supporterà IPv6 entro la fine di quest'anno, è una pessima idea progettare una struttura di database che non sia in grado di gestirlo.
Hendrik Brummermann,


1

È possibile memorizzare fino a 15 caratteri. Non utilizzare VARCHAR (15) perché è di 16 byte (il primo byte gestisce la lunghezza della stringa e quindi il recupero e l'archiviazione più lenti). Usa CHAR (15) sempre su qualcosa come un indirizzo IP.


La lunghezza massima di un indirizzo IP è di 45 caratteri.
Hendrik Brummermann,

CHAR non lo riempirà di spazi?
Gaius,

0

Siamo spiacenti, non posso commentare le risposte. C'è una domanda al riguardo su StackOverflow. E sono totalmente d'accordo con la risposta selezionata: usare 2xBIGINT è probabilmente il modo migliore per ipv6 al momento.

Suggerirei di scegliere 2 * BIGINT, ma assicurati che siano UNSIGNED. Esiste una sorta di divisione naturale al limite dell'indirizzo / 64 in IPv6 (poiché a / 64 è la dimensione del blocco di rete più piccola) che si allineerebbe perfettamente con quella.

È anche possibile archiviare ipv4 su queste origini - contrassegnandone uno NULL o utilizzando il formato V4COMPAT

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.