将geonames.org数据库中的数据导入MySQL DB

时间:2011-03-13 02:07:20

标签: mysql geonames

有人如何将geonames.org数据导入我的数据库?我正在尝试导入的是http://download.geonames.org/export/dump/DO.zip,而我的数据库是MySQL数据库。

4 个答案:

答案 0 :(得分:23)

我通过查看您链接到的zip文件中包含的自述文件在“主要'GeoName'表中包含以下字段找到了以下内容:”

首先在MySQL实例上创建数据库和表。字段的类型在我刚引用上面标题的部分的每一行中给出。

CREATE DATABASE DO_test;
CREATE TABLE `DO_test`.`DO_table` (
  `geonameid` INT,
  `name` varchar(200),
  `asciiname` varchar(200),
  `alternatenames` varchar(5000),
  `latitude` DECIMAL(10,7),
  `longitude` DECIMAL(10,7),
  `feature class` char(1),
  `feature code` varchar(10),
  `country code` char(2),
  `cc2` char(60),
  `admin1 code` varchar(20),
  `admin2 code` varchar(80),
  `admin3 code` varchar(20),
  `admin4 code` varchar(20),
  `population` bigint,
  `elevation` INT,
  `gtopo30` INT,
  `timezone` varchar(100),
  `modification date` date
)
CHARACTER SET utf8;

创建表后,您可以从文件中导入数据。这些字段由制表符分隔,行作为换行符分隔:

LOAD DATA INFILE '/path/to/your/file/DO.txt' INTO TABLE `DO_test`.`DO_table`;

答案 1 :(得分:15)

我最近制作了一个shell脚本,它从geonames站点下载最新数据并将它们导入MySQL数据库。它基于GeoNames论坛的知识,为我节省了很多时间。

它是第一个版本,但功能齐全。也许它可以提供帮助。

您可以http://codigofuerte.github.com/GeoNames-MySQL-DataImport/

访问它

答案 2 :(得分:8)

对于未来的每一个人: 在2008年的geonames.org论坛上,这是“导入所有地理名称转储到MySQL” http://forum.geonames.org/gforum/posts/list/732.page

另外谷歌这个:导入转储到[postgresql OR SQL server OR MySQL]网站:forum.geonames.org

即使从2006年开始,也能找到更多答案

编辑提供概要:

在geoname官方读到我:http://download.geonames.org/export/dump/。我们将找到关于转储文件及其内容的良好描述。

转储文件将直接导入MySQL数据表。例如:

SET character_set_database=utf8;
LOAD DATA INFILE '/home/data/countryInfo.txt' INTO TABLE _geo_countries IGNORE 51 LINES(ISO2,ISO3,ISO_Numeric,FIPSCode,AsciiName,Capital,Area_SqKm,Population,ContinentCode,TLD,CurrencyCode,CurrencyName,PhoneCodes,PostalCodeFormats,PostalCodeRegex,Languages,GeonameID,Neighbours,EquivalentFIPSCodes);
SET character_set_database=default;

请注意字符集,因为如果我们使用2012年旧phpmyadmin的CSV LOAD DATA准备导入程序,即使列的排序规则设置为utf8_general_ci

,我们也可能会丢失utf字符

目前有4个基本数据表:大陆,国家(countryInfo.txt),部门(admin1),城市或地点(地理名称)

admin1,2,3,4转储文件是国家/地区内部部门的不同级别,例如admin 1,即美国或其他国家/地区的省份。 admin 2更详细,是州或省的内部部门。等等3和4

列出的国家/地区转储文件不仅包含城市,还包含该国家/地区的所有地理位置,甚至包括商店中心。还有一个巨大的文件,因为从zip文件中提取后,“allCountries.txt”将超过1GB。如果我们只想要城市,我们应该选择一个转储文件:cities1000.txt,cities5000.txt,cities15000.txt,这些数字代表所列城市的最小人口数。我们将城市存储在地理名称数据表中(您可以将其称为地理位置或地理城市)。

在导入* .txt转储文件之前,请先对MySQL文档中的LOAD DATA语法进行一些研究。

自述文本文件(也在转储页面的页脚中)提供了足够的描述,例如:

The main 'geoname' table has the following fields :
---------------------------------------------------
geonameid         : integer id of record in geonames database
name              : name of geographical point (utf8) varchar(200)
asciiname         : name of geographical point in plain ascii characters, varchar(200)
alternatenames    : alternatenames, comma separated varchar(5000)
latitude          : latitude in decimal degrees (wgs84)
longitude         : longitude in decimal degrees (wgs84)
feature class     : see http://www.geonames.org/export/codes.html, char(1)
feature code      : see http://www.geonames.org/export/codes.html, varchar(10)
country code      : ISO-3166 2-letter country code, 2 characters
cc2               : alternate country codes, comma separated, ISO-3166 2-letter country code, 60 characters
admin1 code       : fipscode (subject to change to iso code), see exceptions below, see file admin1Codes.txt for display names of this code; varchar(20)
admin2 code       : code for the second administrative division, a county in the US, see file admin2Codes.txt; varchar(80) 
admin3 code       : code for third level administrative division, varchar(20)
admin4 code       : code for fourth level administrative division, varchar(20)
population        : bigint (8 byte int) 
elevation         : in meters, integer
dem               : digital elevation model, srtm3 or gtopo30, average elevation of 3''x3'' (ca 90mx90m) or 30''x30'' (ca 900mx900m) area in meters, integer. srtm processed by cgiar/ciat.
timezone          : the timezone id (see file timeZone.txt) varchar(40)
modification date : date of last modification in yyyy-MM-dd format

关于varchar(5000),我们应该知道MySQL 5.0或更高版本中每行的64kb大小: Is a VARCHAR(20000) valid in MySQL?

答案 3 :(得分:1)

这是我成功导入后的注释。

撰写本文时,我在Windows 7上使用MySQL 5.7.16进行测试。请按照以下步骤导入:

  1. official download page下载所需的数据文件。在我的情况下,我选择 cities1000.zip ,因为它的尺寸(21MB)远小于全包 allcountries.zip (1.4GB)。

  2. 根据下载页面上的 readme.txt 创建以下架构和表格,其中字段指定在“主要'geoname'表具有以下字段”的文本下方。

    CREATE SCHEMA geonames DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
    
    CREATE TABLE geonames.cities1000 (
     id                INT,
     name              VARCHAR(200),
     ascii_name        VARCHAR(200),
     alternate_names   VARCHAR(10000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
     latitude          DECIMAL(10, 7),
     longitude         DECIMAL(10, 7),
     feature_class     CHAR(1),
     feature_code      VARCHAR(10),
     country_code      CHAR(2),
     cc2               CHAR(60),
     admin1_code       VARCHAR(20),
     admin2_code       VARCHAR(80),
     admin3_code       VARCHAR(20),
     admin4_code       VARCHAR(20),
     population        BIGINT,
     elevation         INT,
     dem               INT,
     timezone          VARCHAR(100),
     modification_date DATE
    )
     CHARACTER SET utf8;
    

    只要列大小和字段类型与指定的相同,字段名称就是任意的。 alternate_names是使用字符集utf8mb4专门定义的,因为文件中此列的值包含4字节的unicode字符,MySQL的字符集utf8不支持。

  3. 检查这些参数的值:character_set_client,character_set_results,character_set_connection。 7

    SHOW VARIABLES LIKE '%char%';
    

    如果它们不是utf8mb4,那么改变它们:

    SET character_set_client = utf8mb4;
    SET character_set_results = utf8mb4;
    SET character_set_connection = utf8mb4;
    
  4. 使用LOAD DATA INFILE ...

    从文件导入数据
    USE geonames;
    
    LOAD DATA INFILE 'C:\\ProgramData\\MySQL\\MySQL Server 5.7\\Uploads\\cities1000.txt' INTO TABLE cities1000
    CHARACTER SET utf8mb4 (id, name, ascii_name, alternate_names, latitude, longitude, feature_class, feature_code,
                           country_code, cc2, admin1_code, admin2_code, admin3_code, admin4_code, population, @val1,
                           @val2, timezone, modification_date)
    SET elevation = if(@val1 = '', NULL, @val1), dem = if(@val2 = '', NULL, @val2);
    

    声明说明:

    • MySQL应将文件放在指定位置,以便从文件导入数据。您可以使用SHOW VARIABLES LIKE 'secure_file_priv';检查位置。就我而言,它是C:\ProgramData\MySQL\MySQL Server 5.7\Uploads。在Windows中,您需要使用双斜杠来表示路径中的一个斜杠。如果未正确指定路径,则会显示此错误:[HY000][1290] The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

    • 使用CHARACTER SET utf8mb4,您告诉MySQL该文件需要什么样的编码。如果没有明确给出,或者列编码不是utf8mb4,则会出现如下错误提示:[HY000][1300] Invalid utf8 character string: 'Gorad Safija,SOF,Serdica,Sofi,Sofia,Sofiae,Sofie,Sofii,Sofij,Sof' 5 在我的情况下,我发现它是由于替代名称中存在哥特字母,例如(id 727011),(id 3464975)和(id 3893894)。这些字母需要存储为4字节字符(utf8mb4),而我的编码是utf8,最多只支持3字节字符。 6 您可以在创建表后更改列编码:

      ALTER TABLE cities1000 MODIFY alternate_names VARCHAR(10000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
      

      检查列的编码:

      SELECT character_set_name, COLLATION_NAME FROM information_schema.COLUMNS WHERE table_schema = 'geonames' AND table_name = 'cities1000' AND column_name = 'alternate_names';
      

      测试是否可以存储字符:

      UPDATE cities1000 SET alternate_names = '' WHERE id = 1;
      
    • 某些列的值在插入之前需要“改进”,例如elevationdem。它们的类型为INT,文件中的值可能是空字符串,不能由INT类型列存储。因此,您需要将这些空字符串转换为null。声明的后半部分就是为了这个目的。当值未首先进行属性转换时,将显示此错误:[HY000][1366] Incorrect integer value: '' for column 'elevation' at row 1 34

  5. 参考

    1. http://www.geonames.org/
    2. http://download.geonames.org/export/dump/
    3. https://dev.mysql.com/doc/refman/8.0/en/load-data.html
    4. https://dba.stackexchange.com/a/111044/94778
    5. https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-conversion.html
    6. https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
    7. https://stackoverflow.com/a/35156926/4357087
    8. https://dev.mysql.com/doc/refman/5.7/en/charset-connection.html