Get country from IP
how to download databases and compose the query
- Sign up for a free GeoLite2 account
- Log in there, go to download databases, download GeoLite2-Country-Blocks-IPv4.csv and GeoLite2-Country-Locations-en.csv
- Import both csv files to MySQL or MariaDB and rename them to "geoip" and "country". I prefer PhpMyAdmin for that purpose. Header of the csv contains column names - check this option when importing.
- optional: set type integer unsigned for geoname_ip in both tables
- recommended: set indexes to geoname_id (both tables, unique in country) and network (unique in geoip)
The magic query is:
SELECT country_name FROM geoip inner join country on geoip.geoname_id=country.geoname_id WHERE inet_aton('1.2.3.22') & ((-1<<(64-substring_index(network,'/',-1)))>>32) = inet_aton(substring_index(network,'/',1))
With 1.2.3.22 as the test address. The net mask is created for IPv4 on a 64 bit system. You can possibly speed up the query by creating additional rows with the net mask bit number or a pre-converted, indexed integer for the network base address (CIDR). However, in MariaDB 10, a query only takes 0.15 - 0.2 seconds which is acceptable if not too much data is being processed at once.