Recuerde que los PI no son una dirección de texto, sino una identificación numérica. Tengo una situación similar (estamos haciendo búsquedas geo-ip), y si almacena todas sus direcciones IP como enteros (por ejemplo, mi dirección IP es 192.115.22.33, por lo que se almacena como 3228767777), entonces puede buscar direcciones IP fácilmente utilizando operadores de desplazamiento a la derecha.
La desventaja de todos estos tipos de búsquedas es que no puede beneficiarse de los índices y debe realizar una exploración de tabla completa cada vez que realiza una búsqueda. El esquema anterior se puede mejorar almacenando tanto la dirección IP de red de la red CIDR (el comienzo del rango) como la dirección de difusión (el final del rango), por ejemplo, para almacenar 192.168.1.0/24 puede almacenar dos columnas:
network broadcast
3232235776, 3232236031
y luego se puede para que coincidan sólo tiene que hacer
SELECT count(*) FROM bans WHERE 3232235876 >= network AND 3232235876 <= broadcast
Esto permitirá almacenar redes CIDR en la base de datos y el partido contra direcciones IP de forma rápida y eficiente mediante el aprovechamiento de rápida índices numéricos.
Nota de discusión a continuación:
MySQL 5.0 incluye una optimización de la consulta a distancia denominado "index merge intersect", que permite agilizar este tipo de consultas (y evitar escaneos completos de tabla), siempre y cuando:
- 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.
Raspi, Sé que esta pregunta es viejo, pero ... es que su columna cidr el número de uno-bits de la máscara de red, por lo que para IPv6 siempre es 64 y para IPv4 es un número entre 0 y 32? Aunque supongo que 0 prohibiría todas las direcciones ... :) – ErikE