【问题标题】:Loading flatfiles into a normalized MySQL database将平面文件加载到规范化的 MySQL 数据库中
【发布时间】:2010-09-18 20:32:42
【问题描述】:

将数据从平面文件加载到 MySQL 数据库中,然后通过外键创建表之间关系的最快方法是什么?

例如...我有一个格式为:

的平面文件
[INDIVIDUAL]   [POP]  [MARKER]  [GENOTYPE]

"INDIVIDUAL1", "CEU", "rs55555","AA"  
"INDIVIDUAL1", "CEU", "rs535454","GA"  
"INDIVIDUAL1", "CEU", "rs555566","AT"  
"INDIVIDUAL1", "CEU", "rs12345","TT"  
...  
"INDIVIDUAL2", "JPT", "rs55555","AT"  

我需要加载到四个表中:

IND (id,fk_pop,name)  
POP (id,population)  
MARKER (id,rsid)  
GENOTYPE (id,fk_ind,fk_rsid,call)  

具体来说,如何以一种可扩展的方式填充外键?这些数字在 1000 多个个体的范围内,每个个体都有 100 万多个基因型。

【问题讨论】:

  • 感谢您迄今为止的建议......虽然目前我必须在加载之前以编程方式管理外键

标签: mysql performance normalization load-data-infile


【解决方案1】:

我会采取多步骤的方法来做到这一点。

  1. 将数据加载到与您拥有的文件格式匹配的临时表中
  2. 编写查询以执行其他插入,启动通用表,然后执行连接以获取 FK 值。

【讨论】:

    【解决方案2】:

    您可以从没有外键的基表开始。然后,您将在其他表中插入数据时查找 ID。

    另一个想法是您可以用 GUIDs 替换平面文件(INDIVIDUAL1,CEU,...等)中的 ID。然后直接将它们用作 ID 和外键(我注意到这是标记的性能,这可能不会提供最佳的“性能”)。

    【讨论】:

      【解决方案3】:

      有一个更简单的方法。

      首先,确保您对那些应该有一个(名称、人口、rsid)的列有一个 UNIQUE 约束。

      然后使用类似以下的内容:

       LOAD DATA INFILE 'data.txt' IGNORE INTO TABLE POP FIELDS TERMINATED BY ','
          ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES 
          (@name, population, @rsid, @call);
       LOAD DATA INFILE 'data.txt' IGNORE INTO TABLE MARKER FIELDS TERMINATED BY ',' 
          ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES 
          (@name, @population, rsid, @call);
       LOAD DATA INFILE 'data.txt' IGNORE INTO TABLE IND FIELDS TERMINATED BY ',' 
          ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES 
          (name, @population, @rsid, @call) 
          SET fk_pop = (SELECT id FROM POP WHERE population = @population);
       LOAD DATA INFILE 'data.txt' IGNORE INTO TABLE GENOTYPE FIELDS TERMINATED BY ',' 
          ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES 
          (@name, @population, @rsid, call)
          SET fk_ind = (SELECT id FROM IND where name = @name),
          fk_rsid = (SELECT id FROM MARKER where rsid = @rsid);
      

      注意@ 用于表示变量而不是列名的位置。在前 2 个 LOAD DATA 中,这些仅用于忽略数据。在第二个 2 中,它们用于查找外键。

      可能不会很快,请注意 :)。

      【讨论】:

        猜你喜欢
        • 2011-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-07
        • 2011-12-16
        • 2013-07-17
        • 1970-01-01
        相关资源
        最近更新 更多