Cómo almacenar direcciones compatibles con IPv6 en una base de datos relacional


¿Cómo hago eso?

En este momento, IPv6 no se utilizará, pero necesito diseñar la aplicación para que esté lista para IPv6. Es necesario almacenar direcciones IP y bloques CIDR (también BGP NLRI, pero esta es otra historia) en una base de datos MySQL. Siempre he usado un INT para IPv4 + un TINYINT para masklen, pero IPv6 es de 128 bits.

¿Qué enfoque será mejor para eso? 2xBIGINT? CHAR(16) para el almacenamiento binario? CHAR(39) para el almacenamiento de texto? 8xSMALLINT en una tabla?

¿Qué harías ¿recomendar?

 33
Author: the Tin Man, 2009-01-07

6 answers

No estoy seguro de cuál es la respuesta correcta para MySQL dado que aún no admite formatos de direcciones IPv6 de forma nativa (aunque "WL#798: MySQL IPv6 support" sugiere que iba a estar en MySQL v6.0, la documentación actual no lo respalda).

Sin embargo, de los que has propuesto, te sugiero que vayas por 2 * BIGINT, pero asegúrate de que no estén FIRMADOS. Hay una especie de división natural en el límite de la dirección / 64 en IPv6 (ya que un / 64 es el netblock más pequeño tamaño) que se alinearía muy bien con eso.

 19
Author: Alnitak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-21 16:38:43

Tenga en cuenta que la longitud máxima de una dirección IPv6, incluido el identificador de ámbito, es de 46 bytes como se define en INET6_ADDRSTRLEN en las cabeceras C estándar. Para el uso de Internet debe ser capaz de ignorar el identificador de zona (%10, #eth0, etc), pero solo tenga en cuenta cuando getaddrinfo devuelve un resultado más largo de lo esperado.

 6
Author: Steve-o,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-06 04:25:01

Si te inclinas hacia char(16), definitivamente usa binary(16) en su lugar. binario (n) no tiene un concepto de intercalación o conjunto de caracteres (o más bien, es un carácter(n) con un conjunto de caracteres/intercalación de 'binario'). El valor predeterminado para char en mysql es latin1_swedish_ci, lo que significa que intentará una clasificación y comparaciones insensibles a mayúsculas y minúsculas para valores de bytes que son puntos de código válidos en latin1, lo que le causará todo tipo de problemas inesperados.

Otra opción es usar decimal (39, 0) zerofill sin signo, no tan eficiente como dos bigints (decimal usará 4 bytes por nueve dígitos en las versiones actuales de mysql), pero le permitirá mantenerlo todo en una columna e imprimirlo muy bien.

 6
Author: ʞɔıu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-11 17:24:38

Optaría por el formato impreso "estándar" completo de 39 caracteres: {

"2001:0db8:85a3:0000:0000:8a2e:0370:7334"

40 con un terminador nulo.

Este es el formato utilizado por las herramientas de línea de comandos *nix, y, el formato de una dirección IPV6 es normal (?) reported in.

 4
Author: James Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-11 17:23:19

¿La dirección IP va a ser utilizada por un programa para el cual el binario tiene sentido? ¿O sería mejor almacenar una representación de texto? Además, con IPv6, es menos probable que use la dirección en general y más probable que use nombres de host. Si eso es relevante depende de la aplicación, en parte. CHAR (16) sería una mala elección; char es para datos de caracteres y no le gustarán los flujos grandes de cero bytes que prevalecen en las direcciones IPv6. 2 x BIGINT sería incómodo - dos campos que son realmente uno (además es el valor almacenado big-endian o little-endian?). Había utilizado un tipo BINARIO de tamaño fijo, o si eso no está disponible, un tipo blob.

 1
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-07 15:22:49

Estoy trabajando con un proyecto de coincidencia de prefijos más largo, por lo que separo la dirección en 4 enteros para direcciones IPv4. Funciona bien. Lo extendería a direcciones IPv6.

 1
Author: hgl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-11 17:26:21