2011-08-06 18 views
37

Como se solicitó en "ipv6-capable inet_aton and inet_ntoa functions needed", actualmente no existe una función MySQL para almacenar direcciones IPv6. ¿Cuál sería el tipo/función de datos recomendados para almacenar/insertar? (No tengo la intención de almacenarlos como una cadena). Tampoco quiero separar la dirección IPv6 en 2 INT.Almacenamiento de direcciones IPv6 en MySQL

+0

posible duplicado de [Almacenar IPv6 en la base de datos] (http://stackoverflow.com/questions/2049681/store-ipv6-in-database) – knittl

Respuesta

69

¿Qué tal:

BINARY(16) 

Eso debe ser lo suficientemente eficaz.

Actualmente no existe una función para convertir direcciones textuales IPv6 de/a binarias en el servidor MySQL, como se indica en el informe de errores. O necesita hacerlo en su aplicación o posiblemente hacer una UDF (función definida por el usuario) en el servidor MySQL para hacer eso.

ACTUALIZACIÓN:

MySQL 5.6.3 tiene soporte para direcciones IPv6, consulte lo siguiente: "INET6_ATON(expr)".

El tipo de datos es VARBINARY(16) en lugar de BINARY(16) como sugerí anteriormente. La única razón para esto es que las funciones de MySQL funcionan tanto para direcciones IPv6 como IPv4. BINARY(16) está bien para almacenar solo direcciones IPv6 y guarda un byte. VARBINARY(16) se debe usar cuando se manejan direcciones IPv6 e IPv4.

Una implementación para versiones anteriores de MySQL y MariaDB, consulte lo siguiente: "EXTENDING MYSQL 5 WITH IPV6 FUNCTIONS".

+3

Gracias por actualizar esto! – wallyk

+0

¡Tiempo perfecto! Un mes después de haber publicado la pregunta: P – atx

2

Nadie ha publicado una respuesta completa de trabajo (y un montón de ejemplos usar Windows ::1 que puede ser muy engañosa para vivir (o "producción") ambientes) en cualquier lugar (por lo menos que puedo encontrar) así que aquí es:

  1. El formato para almacenar.
  2. Ejemplo INSERT consulta utilizando una dirección IP IPv6 razonablemente compleja.
  3. Ejemplo SELECT consulta que podrá echo devolver la dirección IP IPv6 al cliente.
  4. Solución de problemas para garantizar que no ha omitido ningún código heredado.

me cambiaron todos los nombres de las columnas para ipv6 para reflejar que adecuadamente soporte IPv6 (y que le permite mantener la columna de edad ip intacta). Es posible almacenar la columna ip en la columna ipv6 y luego simplemente gotear la columna ip una vez que esté seguro de que la conversión ha funcionado; cuando en realidad tenga tiempo lo agregaré a esta publicación.

IPv6 Tipo de datos

Como se ha mencionado VARBINARY 16 es la forma conveniente para ir hasta que AMD nos bendice con las CPUs 128 bits y las bases de datos se actualizan para apoyar a 128 bits enteros (no lo digo correctamente?) . IPv6 es de 128 bits, no de 64 bits.

CREATE TABLE `example` 
(
`id` INT(11) NOT NULL AUTO_INCREMENT, 
`ipv6` VARBINARY(16) NOT NULL, 
PRIMARY KEY (`id`) 
) 
COLLATE='utf8mb4_unicode_520_ci' 
ENGINE=InnoDB; 

IPv6 Insertar consulta

es evidente que necesitamos para almacenar una dirección IPv6 IP antes de que podamos SELECT ella; aquí es la PHP/SQL código:

$ipv6 = mysqli_real_escape_string($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329'); 
$query1 = "INSERT INTO example (ipv6) VALUES (INET6_ATON('$ipv6'));"; 

IPv6 consulta SELECT

El PHP/SQL código:

$ipv6 = mysqli_real_escape_string($db,'FE80:0000:0000:0000:0202:B3FF:FE1E:8329'); 
$query2 = "SELECT INET6_NTOA(ipv6) AS ipv6 FROM example WHERE ipv6=INET6_ATON('$ipv6');"; 

Esto devolverá fe80::202:b3ff:fe1e:8329; no, no es el IPv6 completo (que es FE80:0000:0000:0000:0202:B3FF:FE1E:8329), es una versión condensada/abreviada. Hay un código para convertirlo en la versión formal de longitud completa, pero esto es para ahorrarme tiempo a mí mismo y a los demás porque este Q/A es el que sigue apareciendo.

Importante: sólo porque algunos direcciones IPv6 mirada como si hubieran encajan en bigint hace no implican dos minutos más tarde, alguien con una dirección IPv6 más grande no va a pasar por aquí y causar estragos.

Esperemos que esto ahorrará a algunas personas la locura de abrir otras dos docenas de pestañas. Cuando tenga tiempo en el futuro, agregaré el código PHP adicional que amplía el IPv6 condensado al formato formal completo.


Solución de problemas

Si por alguna razón el almacenamiento y/o recuperación de direcciones IPv6 que no funciona para usted, entonces usted agarra una copia de Advanced Find and Replace (funciona más rápido en el vino que la de Linux nativo grep); utilice este predominantemente para buscar, no reemplazar. Asegúrese de que su código sea consistente en todas partes de su software.

  • Todas las variables $ip deben ser convertidos a $ipv6 por lo que sabes que tienes que poco cubierto.
  • No se olvide de quitar el ) terminando por los siguientes cuatro pasos:
  • Buscar todas las instancias de PHP inet_pton( funciones y eliminarlos.
  • Buscar todas las instancias de PHPinet_ntop( funciones y eliminarlas.
  • Buscar todas las instancias de SQLINET_ATON( funciones y eliminarlas.
  • Buscar todas las instancias de SQLINET_NTOA( funciones y eliminarlas.
  • Busque todas las instancias de $ipv6 y asegúrese de que todas las instancias de IP-IN-TO-SQL usen INET6_ATON('$ipv6') y que todas las instancias donde IP-FROM-SQL usan INET6_NTOA(ipv6) AS ipv6.
  • Busque todas las instancias de $row1['ip'] y reemplácelas por $row1['ipv6'].
  • Asegúrese de que todas las instancias de $ipv6 = usan el siguiente código (con la referencia de objeto de base de datos modificada): $ipv6 = (isset($_SERVER['REMOTE_ADDR']) && strlen($_SERVER['REMOTE_ADDR']) > 0) ? mysqli_real_escape_string($db,$_SERVER['REMOTE_ADDR']) : mysqli_real_escape_string($db,getenv('REMOTE_ADDR'));.
  • asegurarse de que sus pruebas utilizan recién probado direcciones IP en lugar de versiones potencialmente fallidos si usted es consciente de que había algo mal antes de comenzar la depuración.
Cuestiones relacionadas