sql >> Database teknologi >  >> RDS >> Mysql

Er der en måde at matche IP med IP+CIDR ​​direkte fra SELECT-forespørgsel?

Husk at IP'er ikke er en tekstadresse, men et numerisk ID. Jeg har en lignende situation (vi laver geo-ip-opslag), og hvis du gemmer alle dine IP-adresser som heltal (min IP-adresse er f.eks. 192.115.22.33, så den er gemt som 3228767777), så kan du slå IP-adresser op nemt ved at bruge højreskifteoperatører.

Ulempen ved alle disse typer opslag er, at du ikke kan drage fordel af indekser, og du skal lave en fuld tabelscanning, hver gang du foretager et opslag. Ovenstående skema kan forbedres ved at gemme både netværks-IP-adressen for CIDR-netværket (begyndelsen af ​​området) og broadcast-adressen (slutningen af ​​området), så for eksempel for at gemme 192.168.1.0/24 kan du gemme to kolonner:

network     broadcast
3232235776, 3232236031 

Og så kan du bare gøre det for at matche det

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

Dette ville lade dig gemme CIDR-netværk i databasen og matche dem mod IP-adresser hurtigt og effektivt ved at drage fordel af hurtige numeriske indekser.

Note fra diskussion nedenfor :

MySQL 5.0 indeholder en rækkeviddeforespørgselsoptimering kaldet "indeksflet skærer " som gør det muligt at fremskynde sådanne forespørgsler (og undgå fuld tabelscanninger), så længe:

  • Der er et indeks med flere kolonner, der matcher nøjagtigt kolonnerne i forespørgslen i rækkefølge. Så - for ovenstående forespørgselseksempel skal indekset være (network, broadcast) .
  • Alle data kan hentes fra indekset. Dette gælder for COUNT(*) , men er ikke sandt for SELECT * ... LIMIT 1 .

MySQL 5.6 indeholder en optimering kaldet MRR, som også ville fremskynde fuld række hentning, men det er uden for dette svars omfang.



  1. UnsatisfiedLinkError i native metode

  2. Installation af PostgreSQL på Ubuntu til Ruby on Rails

  3. SQL:IF-sætning i WHERE-sætning

  4. Python-databaseprogrammering med SQL Express for begyndere