2011-02-27 16 views
80

Duplicar posible:
How to store an IP in mySQL¿Qué tipo de datos MySQL usar para una dirección IP?

Quiero obtener la dirección IP desde $_SERVER['REMOTE_ADDR'] y algunas otras variables de $_SERVER, que tipo de datos es el más adecuado para esto?

¿Es VARCHAR(n)?

+0

ver este [discusión] (http://forums.mysql.com/read. php? 21,49094,49094 # msg-49094) – Ragnar123

+8

No estoy de acuerdo con que esta sea una pregunta duplicada, ya que la otra pregunta es específicamente una pregunta relacionada con el rendimiento para almacenar una gran cantidad de direcciones IP. La respuesta a esa pregunta podría no ser relevante para alguien que no esté interesado en maximizar el uso o el rendimiento del espacio. – User

+0

@User He hecho esta pregunta hace aproximadamente un año y medio;) Pero gracias por compartir tu opinión. – ComFreek

Respuesta

123

Dado que las direcciones IPv4 son 4 bytes de largo, se puede usar un INT (UNSIGNED) que tiene exactamente 4 bytes:

`ipv4` INT UNSIGNED 

y INET_ATON y INET_NTOA para convertirlos:

INSERT INTO `table` (`ipv4`) VALUES (INET_ATON("127.0.0.1")); 
SELECT INET_NTOA(`ipv4`) FROM `table`; 

Para direcciones IPv6 se puede utilizar una vez BINARY:

`ipv6` BINARY(16) 

Y el uso de PHP’s inet_pton y inet_ntop para la conversión:

'INSERT INTO `table` (`ipv6`) VALUES ("'.mysqli_real_escape_string(inet_pton('2001:4860:a005::68')).'")' 
'SELECT `ipv6` FROM `table`' 
$ipv6 = inet_pton($row['ipv6']); 
+5

La sintaxis para 5.1 es INT NO SEÑALADA, no UNSIGNED INT –

+0

Con el método sugerido: ¿cómo encontrar direcciones con subred coincidente? –

+1

@AlexanderFarber [Compruebe si el IP está en la subred] (http://stackoverflow.com/a/10002060/53114) – Gumbo

39

tiene dos posibilidades (para una dirección IPv4):

  • un varchar(15), si su desea almacenar la dirección IP como una cadena
    • 192.128.0.15 por ejemplo
  • un integer (4 bytes), si convierte la dirección IP a un entero
    • 3229614095 para el IP que usaba antes


La segunda solución requerirá menos espacio en la base de datos, y es probablemente una mejor opción, incluso si implica un poco de manipulaciones al almacenar y recuperar los datos (convirtiéndolo de/a una cadena).

Sobre esas manipulaciones, ver las ip2long() y long2ip() funciones, en el lado de PHP, o inet_aton() y inet_ntoa() en el lado de MySQL.

+0

Pero he oído que también puede ser una dirección IPv6 en $ _SERVER ['REMOTE_ADDR']. ¿Y cómo podría convertir algo como xxx.xx.xx.xxx en un entero (4 bytes) como dijiste? – ComFreek

+1

Para una dirección IPv6, necesitará más de 4 bytes: https://secure.wikimedia.org/wikipedia/en/wiki/IPv6 dice que usa 128 bits, por lo que 16 bytes ;; en PHP, consulte http://fr2.php.net/manual/en/function.inet-pton.php –

+0

¿Qué tipo de datos sería correcto para 16 bytes? – ComFreek

5

Para las direcciones IPv4, puede usar VARCHAR para almacenarlas como cadenas, pero también intente almacenarlas como integradores largas INT(11) UNSIGNED. Puede usar la función INET_ATON() de MySQL para convertirlos a representación entera.La ventaja de esto es que le permite hacer comparaciones fáciles sobre ellos, al igual que BETWEEN consultas

INET_ATON() MySQL function

Cuestiones relacionadas