2010-03-29 9 views
57

Qual è il modo più efficiente per archiviare e recuperare gli indirizzi IP in MySQL? In questo momento sto facendo:Il modo più efficiente per memorizzare l'indirizzo IP in MySQL

SELECT * FROM logins WHERE ip = '1.2.3.4' 

Dove IP è un campo VARCHAR(15).

C'è un modo migliore per farlo?

+11

Ok, quindi il tuo programma è rotto o non funziona affatto con IPv6 ... sigh. – Juliano

risposta

95

Per IPv4 addresses, si consiglia di memorizzarli come un int unsigned e utilizzare i INET_ATON() e INET_NTOA() funzioni per restituire l'indirizzo IP dal suo valore numerico, e viceversa.

Esempio:

SELECT INET_ATON('127.0.0.1'); 

+------------------------+ 
| INET_ATON('127.0.0.1') | 
+------------------------+ 
|    2130706433 | 
+------------------------+ 
1 row in set (0.00 sec) 


SELECT INET_NTOA('2130706433'); 

+-------------------------+ 
| INET_NTOA('2130706433') | 
+-------------------------+ 
| 127.0.0.1    | 
+-------------------------+ 
1 row in set (0.02 sec) 
+4

non memorizzerete come 'INT' ma' INT UNSIGNED'. mi piace l'uso di funzioni appositamente integrate però. +1 – pstanton

+0

Grazie. Sai se esiste una funzione Python per questo? – ensnare

+0

@ensnare: Sì, controlla questo: http://snipplr.com/view/14807/convert-ip-to-int-and-int-to-ip/. –

4

La cosa più importante è assicurarsi che la colonna sia indicizzata. Questo potrebbe fare un'enorme differenza nelle query basate sull'indirizzo IP.

+0

La mia comprensione è che gli indici su un varchar sono di assistenza limitata. – flickerfly

1

forse memorizzare il valore intero direttamente in un campo intero? Un indirizzo IP è fondamentalmente 4 "cortometraggi".

Check it out: http://en.kioskea.net/faq/945-converting-a-32-bit-integer-into-ip

+0

quindi lo memorizzerebbe in quattro campi? e sarebbero byte, no? 2^8 ogni volta In alternativa, è possibile convertirli in numeri decimali e memorizzare il decimale, anche se sarebbe un campo più grande, sarebbe un campo singolo. – jcolebrand

+1

Un vernacolo più appropriato sarebbe dire che un indirizzo IP è 4 byte. –

+0

Ho capito l'essenza. Brian sta dicendo che concettualmente un int è composto da quattro cortometraggi. Un corto è un byte. Un int è 4 byte. Come detto altrove su questa pagina, deve essere un int unsigned. – joe

52

Se si desidera solo per memorizzare gli indirizzi IPv4, allora si può memorizzare in un campo intero a 32 bit.

Se si desidera supportare anche IPv6, una stringa è probabilmente il modo più facile da leggere/utilizzare (sebbene sia possibile archiviarli tecnicamente in un campo VARBINARY() a 16 byte, sarebbe fastidioso provare a generare Istruzioni SQL da selezionare per indirizzo IP "a mano")

+18

+1: l'unica risposta che prevede l'utilizzo di IPv6 – Juliano

+3

Proprio quando si usa IPV6 le funzioni sono diverse (INET6_ATON (ip)). IPV4 ha bisogno di VARBINARY (4) e IPV6 necessiterebbe di VARBINARY (16) (che ovviamente funziona anche per gli indirizzi V4). È possibile convertire un V4 IP (INT) in un formato compatibile come questo: INET6_ATON (INET_NTOA (ip)) – John

1

Qualunque sia il modo più semplice con cui lavorare. Il problema delle dimensioni o della velocità non è un problema finché non si è certi che si tratta di un problema mediante la creazione di profili. In alcuni casi, una stringa potrebbe essere più semplice da utilizzare se è necessario eseguire una corrispondenza parziale. Ma come problema di spazio o prestazioni, non ti preoccupare a meno che tu non abbia motivo di preoccuparti.