Mysql
 sql >> Base de données >  >> RDS >> Mysql

Existe-t-il un moyen de faire correspondre IP avec IP + CIDR directement à partir de la requête SELECT ?

N'oubliez pas que les adresses IP ne sont pas une adresse textuelle, mais un identifiant numérique. J'ai une situation similaire (nous faisons des recherches géo-ip), et si vous stockez toutes vos adresses IP sous forme d'entiers (par exemple, mon adresse IP est 192.115.22.33 donc elle est stockée sous 3228767777), alors vous pouvez rechercher des IP facilement en utilisant les opérateurs de décalage à droite.

L'inconvénient de tous ces types de recherches est que vous ne pouvez pas bénéficier des index et que vous devez effectuer une analyse complète de la table chaque fois que vous effectuez une recherche. Le schéma ci-dessus peut être amélioré en stockant à la fois l'adresse IP du réseau CIDR (le début de la plage) et l'adresse de diffusion (la fin de la plage), donc par exemple pour stocker 192.168.1.0/24 vous pouvez stocker deux colonnes :

network     broadcast
3232235776, 3232236031 

Et puis vous pouvez le faire correspondre, vous le faites simplement

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

Cela vous permettrait de stocker les réseaux CIDR dans la base de données et de les associer rapidement et efficacement aux adresses IP en tirant parti des index numériques rapides.

Note de la discussion ci-dessous :

MySQL 5.0 inclut une optimisation de requête à distance appelée "intersection de fusion d'index " qui permet d'accélérer de telles requêtes (et d'éviter les analyses complètes de la table), tant que :

  • Il existe un index multi-colonnes qui correspond exactement aux colonnes de la requête, dans l'ordre. Donc - pour l'exemple de requête ci-dessus, l'index devrait être (network, broadcast) .
  • Toutes les données peuvent être extraites de l'index. Ceci est vrai pour COUNT(*) , mais n'est pas vrai pour SELECT * ... LIMIT 1 .

MySQL 5.6 inclut une optimisation appelée MRR qui accélérerait également la récupération complète des lignes, mais cela sort du cadre de cette réponse.