Almacenar dirección IP

25

Tengo que almacenar la dirección IP de todos los usuarios registrados en la base de datos. Me pregunto, ¿cuántos caracteres debo declarar para esa columna?

¿Debo admitir también IPv6? Si es así, ¿cuál es la longitud máxima de la dirección IP?

Cleankod
fuente

Respuestas:

27

No almacenar como una cadena. Use una int unsignedcolumna y almacene / recupere con INET_ATON()y INET_NTOA()respectivamente. AFAIK mysql no es compatible con INET_ * para ipv6.

EDITAR según el comentario

El uso de la función integrada para convertir IP a / desde enteros (y almacenar esos enteros en la base de datos) tiene el efecto secundario de validar automáticamente esas IP. Digamos que almacena una IP como VARCHAR (16), debe asegurarse de no almacenar IP no válidas (como 999.999.999.999 como ejemplo) con alguna validación personalizada. Las funciones INET_ * se encargan de eso.

Señor shunz
fuente
1
-1, las direcciones IP son de hasta 128 bits y el tipo entero más grande admitido por MySQL es de 64 bits.
Hendrik Brummermann
3
IPv4 es de 32 bits. 128 bits es para IPv6, que, como mencionó, el material INET_ * no es compatible.
Richard
1
Para la dirección IPv6, use las funciones INET6_ATON () e INET6_NTOA (), vea el ejemplo - rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
rathishDBA
6

Probablemente sea hora de comenzar a considerar IPv6. MySQL no tiene métodos para convertir direcciones IPv6 a formato binario. Una cadena de cuarenta caracteres manejará cualquier dirección IPv6 normal. Hay un formato que podría superar los 40 caracteres, consideraría que es poco probable que ocurra la práctica.

Puede calcular el tamaño a partir de la información de que habrá como máximo 8 grupos de cuatro caracteres con 7 caracteres separadores. El formato anormal reemplaza los dos últimos grupos con una dirección de formato IPv4. Sin compresión de dirección, reemplaza los últimos 9 caracteres con hasta 15 caracteres.

Si está almacenando bloques, la indicación del tamaño del bloque puede tomar 4 caracteres en lugar de los 3 caracteres necesarios para IPv4.

Debe asegurarse de que el formato que obtiene sea consistente, pero todo el software que he visto proporciona formatos consistentes para las direcciones.

BillThor
fuente
2
Estoy totalmente de acuerdo, viene IPv6 y es mejor estar preparado para ello que esperarlo como Y2K: D
Jeff
No solo viene, sino que ya está aquí en mis sistemas.
BillThor
6

Sugeriría la migración a PostgreSQL y el uso de tipos de datos INET o CIDR .

CREATE TABLE test ( test_id serial PRIMARY KEY, address inet );
INSERT INTO test ( address ) VALUES ( '1.2.3.4'::inet );
INSERT INTO test ( address ) VALUES ( 'a:b::c:d'::inet );
SELECT * FROM test;
 test_id | address  
---------+----------
       1 | 1.2.3.4
       2 | a:b::c:d
jkj
fuente
Para obtener qué IP están en una red, SELECCIONE * DE la prueba DONDE dirección << '1.2.3.0/24'::inet;
jkj
4

Aquí está la mejor respuesta hecha en una de las listas de correo de MySQL. Leer Mejor FieldType para almacenar la dirección IP ... .

Brevemente sugiere, lo que segundo, usar INT (10) UNSIGNED.

  1. Utiliza menos memoria (solo 4 bytes)
  2. Lo mejor para ordenar y buscar los rangos de IP, especialmente si busca el país de origen de sus visitantes.

Entonces, usando 192.168.10.50:

(192 * 2 ^ 24) + (168 * 2 ^ 16) + (10 * 2 ^ 8) + 50 = 3232238130 (resulta en 192.168.10.50)

En MySQL, puede usar directamente SELECT INET_ATON('192.168.10.50'); para obtener 3232238130.

O

192 + (168 * 2 ^ 8) + (10 * 2 ^ 16) + (50 * 2 ^ 24) = 839559360 (Al revés, resulta en 50.10.168.192)

En MySQL, puede usar directamente SELECT INET_NTOA(3232238130); para 192.168.10.50volver.

Ojo
fuente
Impresionante, +1 para ti !!! El uso de 4 bytes sin signo seguro supera la manipulación de cadenas en cualquier momento.
RolandoMySQLDBA
-1, las direcciones IP son de hasta 128 bits y el tipo entero más grande admitido por MySQL es de 64 bits.
Hendrik Brummermann
3
nhnb, IPv6 es de 128 bits, pero la conversación es sobre IPv4, que es de 32 bits. No es necesario comentar sobre cada comentario / respuesta insistiendo en su conocimiento.
Ojo
Su respuesta no menciona que solo trata con el antiguo protocolo de Internet, mientras que la pregunta menciona explícitamente IPv6 al final. Dado que el último proveedor principal de internet (al menos en mi país) admitirá IPv6 antes de fin de año, es una idea extremadamente mala diseñar una estructura de base de datos que no pueda manejarlo.
Hendrik Brummermann
1

Puede almacenar hasta 15 caracteres. No utilice VARCHAR (15) porque son 16 bytes (el primer byte gestiona la longitud de la cadena y, por lo tanto, una recuperación y almacenamiento más lentos). Use CHAR (15) siempre en algo como una dirección IP.

RolandoMySQLDBA
fuente
La longitud máxima de una dirección IP es de 45 caracteres.
Hendrik Brummermann
¿CHAR no lo rellenará con espacios?
Cayo
0

Lo siento, no puedo comentar sobre las respuestas. Hay una pregunta al respecto en stackoverflow. Y estoy totalmente de acuerdo con la respuesta seleccionada: usar 2xBIGINT es probablemente la mejor manera para ipv6 actualmente.

Sugeriría ir por 2 * BIGINT, pero asegúrese de que estén SIN FIRMAR. Hay una especie de división natural en el límite de dirección / 64 en IPv6 (ya que a / 64 es el tamaño de bloque de red más pequeño) que se alinearía muy bien con eso.

También es posible almacenar ipv4 en estos bigints, ya sea marcando uno de ellos como NULL o utilizando el formato V4COMPAT

rvs
fuente