sql >> Base de Datos >  >> RDS >> Mysql

¿Hay alguna forma de hacer coincidir IP con IP+CIDR ​​directamente desde la consulta SELECT?

Recuerda que las IP no son una dirección de texto, sino una identificación numérica. Tengo una situación similar (estamos haciendo búsquedas de IP geográficas), y si almacena todas sus direcciones IP como números enteros (por ejemplo, mi dirección IP es 192.115.22.33, por lo que se almacena como 3228767777), entonces puede buscar IP fácilmente mediante el uso de operadores de desplazamiento a la derecha.

La desventaja de todos estos tipos de búsquedas es que no puede beneficiarse de los índices y tiene que hacer una exploración completa de la tabla cada vez que realiza una búsqueda. El esquema anterior se puede mejorar almacenando tanto la dirección IP de la red CIDR (el comienzo del rango) como la dirección de transmisión (el final del rango), por lo que, por ejemplo, para almacenar 192.168.1.0/24 puede almacenar dos columnas:

network     broadcast
3232235776, 3232236031 

Y luego puedes combinarlo, simplemente lo haces

SELECT count(*) FROM bans WHERE 3232235876 >= network AND 3232235876 <= broadcast

Esto le permitiría almacenar redes CIDR en la base de datos y compararlas con las direcciones IP de manera rápida y eficiente aprovechando los índices numéricos rápidos.

Nota de la discusión a continuación :

MySQL 5.0 incluye una optimización de consultas a distancia llamada "intersección de fusión de índice " que permite acelerar este tipo de consultas (y evitar exploraciones de tablas completas), siempre que:

  • Hay un índice de varias columnas que coincide exactamente con las columnas de la consulta, en orden. Entonces, para el ejemplo de consulta anterior, el índice debería ser (network, broadcast) .
  • Todos los datos se pueden recuperar del índice. Esto es cierto para COUNT(*) , pero no es cierto para SELECT * ... LIMIT 1 .

MySQL 5.6 incluye una optimización llamada MRR que también aceleraría la recuperación de filas completas, pero eso está fuera del alcance de esta respuesta.