2010-03-29 39 views
57

¿Cuál es la forma más eficiente de almacenar y recuperar direcciones IP en MySQL? En este momento estoy haciendo:La forma más eficiente de almacenar direcciones IP en MySQL

SELECT * FROM logins WHERE ip = '1.2.3.4' 

Donde IP es un campo VARCHAR(15).

¿Hay una mejor manera de hacerlo?

+11

Ok, entonces su programa está roto o no funciona en absoluto con IPv6 ... suspiro. – Juliano

Respuesta

95

Para IPv4 addresses, es posible que desee guardarlas como un int unsigned y utilizar los INET_ATON() y INET_NTOA() funciones para devolver la dirección IP de su valor numérico, y viceversa.

Ejemplo:

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

no almacenarías como 'INT' pero' INT UNSIGNED'. Sin embargo, me gusta el uso de funciones incorporadas deliberadamente. +1 – pstanton

+0

Gracias. ¿Sabes si hay una función de pitón para esto? – ensnare

+0

@ensnare: Sí, verifique esto: http://snipplr.com/view/14807/convert-ip-to-int-and-int-to-ip/. –

4

Lo más importante es asegurarse de que la columna esté indexada. Esto podría marcar una gran diferencia en las consultas basadas en la dirección IP.

+0

Según tengo entendido, los índices en un varchar son de asistencia limitada. – flickerfly

1

¿puede almacenar el valor entero directamente en un campo entero? Una dirección IP es básicamente 4 "cortos".

Compruébelo usted mismo: http://en.kioskea.net/faq/945-converting-a-32-bit-integer-into-ip

+0

para que lo almacene en cuatro campos? y serían bytes, ¿no? 2^8 cada vez Alternativamente, podría convertirlos a números decimales y almacenar el decimal, aunque ese sería un campo más grande, sería un campo único. – jcolebrand

+1

Una lengua vernácula más apropiada sería decir que una dirección IP es de 4 bytes. –

+0

Tengo la esencia. Brian dice que conceptualmente una int está compuesta de cuatro cortos. Un corto es un byte. Un int es 4 bytes. Como se dijo en otra parte de esta página, debe ser una int sin firmar. – joe

52

Si sólo desea almacenar las direcciones IPv4, entonces se puede almacenar en un campo entero de 32 bits.

Si también quieres admitir IPv6, una cadena es probablemente la más fácil de leer/usar (aunque técnicamente puedes almacenarla en un campo de 16 bytes VARBINARY(), sería molesto tratar de generar Declaraciones SQL para seleccionar por dirección IP "a mano")

+18

+1: la única respuesta que predice el uso de IPv6 – Juliano

+3

Justo cuando se utiliza IPV6 las funciones son diferentes (INET6_ATON (ip)). IPV4 necesita VARBINARY (4) e IPV6 necesitaría VARBINARY (16) (que por supuesto también funciona para direcciones V4). Puede convertir un V4 IP (INT) a un formato compatible como este: INET6_ATON (INET_NTOA (ip)) – John

1

Lo que sea más fácil para usted para trabajar. El problema de tamaño o velocidad no es un problema hasta que sepa que es un problema mediante el uso de perfiles. En algunos casos, una cadena puede ser más fácil de trabajar si necesita hacer una coincidencia parcial. Pero como un problema de espacio o rendimiento, no te preocupes a menos que tengas un motivo real para preocuparte.

Cuestiones relacionadas