Geonames database: getting a full hierarchy (country -> admin1 -> admin2 -> city) with one only mysql query

自古美人都是妖i 提交于 2019-12-11 02:50:52

问题


i'm trying to use geonames database (downloaded and loaded on a local mysql) to get all associated informations from a location (lowest level is cityname) using Java and JDBC drivers.

I have a big performance issue: each query takes something like 4-5 seconds, and i have to split the query in three parts before getting all the results i need.

Basically, i have loaded the allCountries database, the admin1codes and the admin2codes. Since admin1 and admin2 unique ids are composed by information retrieved from the query on allcountries, i had to do something like this to query the database:

String query = "SELECT DISTINCT "
             + "loc_geoname.name AS name,"
             + "loc_geoname.asciiname AS asciiname,"
             + "loc_geoname.alternatenames AS alternames,"
             + "loc_geoname.latitude AS latitude,"
             + "loc_geoname.longitude AS longitude,"
             + "loc_geoname.country AS country_code,"
             + "loc_geoname.admin1 AS admin1, "
             + "loc_geoname.admin2 AS admin2, "
             + "loc_countryinfo.name AS country, "
             + "loc_countryinfo.currency AS value "
             + "FROM loc_geoname, loc_countryinfo "
             + "WHERE loc_countryinfo.iso_alpha2=loc_geoname.country "
             + "AND loc_geoname.asciiname IN (" + search + ") "
             + "AND loc_geoname.country='" + countrycode + "' "
             + "AND loc_geoname.fcode like 'PP%' limit 10;"

and this is the query i'm using to fetch all the info for a city (search and countrycode are strings prebuild, they're not important)

now, to get the admin1 name and the admin2 name i have to launch two new queries:

String a1 = res.getString("admin1");
String query_area = "select name from loc_admin1Codes where code='" + countrycode + "." + a1 + "';";

String a2 = res.getString("admin2");
String query_district = "select name from loc_admin2Codes where code='" + countrycode + "." + a1 + "." + a2 + "';";

I'm sure its possible to combine the two queries into one (but not so sure) but i don't know how to create the admin1 and admin2 codes without getting them values from the first query and combining strings into the second and the third.

Also, i'm sure i can improve my first query to speed it up a bit (maybe using joins instead of a cross combination with a where clause...)

Table structure is the same as defined here and i didn't change anything from that. Thanks all in advance for the hints!


回答1:


You shouldn't request it every time.

I did this by adding a column "admin1Nameé and "admin2Name" and I updated their value with a simple SQL query.

This database is very large so you should think about calculated column.

EDIT : if you still want to do it every time

SELECT 
    locgeoname.*, 
    loc_countryinfo.name, loc_admin1Codes.name, loc_admin2Codes.name, 
FROM 
    loc_geoname 
INNER JOIN 
    loc_countryinfo ON loc_countryinfo.iso_alpha2 = loc_geoname.country
INNER JOIN 
    loc_admin1Codes ON code = loc_countryinfo.iso_alpha2 + '.' + admin1  
INNER JOIN 
    loc_admin2Codes ON code = loc_countryinfo.iso_alpha2 + '.' + admin1 + '.' + admin2


来源:https://stackoverflow.com/questions/7319820/geonames-database-getting-a-full-hierarchy-country-admin1-admin2-city

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!