Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“如何进口”;“很多”;使用PHP和外键将数据传输到MySQL?_Php_Mysql_Insert_Large Data - Fatal编程技术网

“如何进口”;“很多”;使用PHP和外键将数据传输到MySQL?

“如何进口”;“很多”;使用PHP和外键将数据传输到MySQL?,php,mysql,insert,large-data,Php,Mysql,Insert,Large Data,我有这些桌子: create table person ( person_id int unsigned auto_increment, person_key varchar(40) not null, primary key (person_id), constraint uc_person_key unique (person_key) ) -- person_key is a varchar(40) that identifies an indivi

我有这些桌子:

create table person (
    person_id int unsigned auto_increment, 
    person_key varchar(40) not null, 
    primary key (person_id), 
    constraint uc_person_key unique (person_key)
) 
-- person_key is a varchar(40) that identifies an individual, unique 
-- person in the initial data that is imported from a CSV file to this table

create table marathon (
    marathon_id int unsigned auto_increment,  
    marathon_name varchar(60) not null, 
    primary key (marathon_id) 
)

create table person_marathon (
    person_marathon _id int unsigned auto_increment,  

    person_id int unsigned, 
    marathon_id int unsigned,

    primary key (person_marathon_id),
    foreign key person_id references person (person_id), 
    foreign key marathon_id references person (marathon_id),

    constraint uc_marathon_person unique (person_id, marathon_id)  
)
Person表由包含约130000行的CSV填充。此CSV包含每个人和其他一些人数据的唯一varchar(40)。CSV中没有ID

对于每一场马拉松,我都会得到一份CSV,其中包含1-3万人的名单。CSV基本上只包含一个
person\u key
值列表,显示哪些人参加了特定的马拉松比赛

将数据导入
人马拉松
表以维护FK关系的最佳方式是什么?

以下是我目前能想到的想法:

  • person\u id+person\u键
    信息从MySQL中拉出,并在PHP中合并
    person\u marathon
    数据,以在插入
    person\u marathon
    表之前获得
    person\u id

  • 使用临时表插入。。。但这是为了工作,我被要求永远不要在这个特定的数据库中使用临时表

  • 不要使用
    person\u id
    ,只需使用
    person\u key
    字段,但我必须加入
    varchar(40)
    ,这通常不是一件好事

  • 或者,对于insert,让它看起来像这样(我必须插入

    ,否则它不会将整个insert格式化为代码):

    这个插入的问题是,要在PHP中构建它,导入的人员列表将是巨大的,因为它很容易是30000个
    selectunion
    项。不过,我不知道还能怎么做


我处理过类似的数据转换问题,但规模较小。如果我正确理解了你的问题(我不确定),那么让你面临挑战的细节似乎是:你试图在同一步中做两件事:

  • 将大量行从CSV导入mysql,然后

  • 进行转换,使person marathon关联通过person_id和marathon_id工作,而不是(笨拙且不受欢迎的)varchar personkey列
简而言之,我会尽一切可能避免同时做这两件事。将其分为这两个步骤——首先以可接受的形式导入所有数据,然后对其进行优化。Mysql是进行这种转换的良好环境,因为当您将数据导入persons和marathons表时,ID是为您设置的

步骤1:导入数据

  • 我发现在mysql环境中执行数据转换比在mysql环境之外更容易。因此,将数据输入mysql,以一种即使不是最优的方式也能保留个人马拉松关联的形式,并担心以后会改变关联方法
  • 你提到临时工作台,但我认为你不需要。在persons_marathons表上设置一个临时列“personkey”。导入所有关联时,暂时将person_id留空,只需导入personkey即可。重要的是,确保personkey是associations表和persons表上的索引列。然后,您可以稍后再检查并为每个personkey填写正确的person\u id,而不用担心mysql效率低下
  • 我不清楚马拉松表格数据的性质。你有成千上万的马拉松比赛要参加吗?如果是这样,我并不羡慕你在马拉松比赛中处理1份电子表格的工作。但是如果少一点,那么你也许可以用手摆好马拉松的桌子。让mysql为您生成马拉松ID。然后,在为每个马拉松导入person_marathon CSV时,请确保在与该马拉松相关的每个关联中指定该马拉松ID
导入完数据后,将有三个表: *persons-您拥有丑陋的personkey、新生成的person\u id以及任何其他字段 *马拉松-此时你应该有一个马拉松id,对吗?要么是新生成的,要么是您从某个旧系统继承的数字。 *人员马拉松-此表应填写马拉松id并指向马拉松表中的正确行,对吗?您还有personkey(丑陋但存在)和person_id(仍然为空)

步骤2:使用personkey为关联表中的每一行填写person_id

然后,您可以使用直接Mysql,或者编写一个简单的PHP脚本,为persons_marathons表中的每一行填写person_id。如果我无法让mysql直接执行此操作,我通常会编写一个php脚本,一次处理一行。其中的步骤很简单:

  • 查找person\u id为null但personkey不为null的任何一行
  • 查一下那个人的身份证
  • 在该行的关联表中写入该人员的id
  • 您可以告诉PHP重复100次,然后结束脚本,或者1000次,如果您一直遇到超时问题或类似于taht的问题

    此转换涉及大量查找,但每个查找只需要针对一行。这很有吸引力,因为在任何时候都不需要要求mysql(或PHP)“将整个数据集保存在其头部”


    此时,您的associations表应该为每一行填写person_id。现在可以安全地删除personkey列了,瞧,您有了高效的外键。

    您有没有为此研究过ETL过程?Pentaho PDI可能是吗?我更希望能够用PHP编写一些东西。我只是不确定构造插入的最佳方法。我想我倾向于取出
    person\u id+person\u键
    ,然后在插入MySQL之前将其合并到PHP中。这是一个非常小的项目,我不确定我们是否需要一个新的工具来处理它。你应该试试Pentaho。我用la做了很多大的导入(几GB)
    insert  into person_marathon 
    
    select  p.person_id, m.marathon_id
    
    from    ( select 'person_a' as p_name, 'marathon_a' as m_name union 
              select 'person_b' as p_name, 'marathon_a' as m_name ) 
              as imported_marathon_person_list 
    
            join person p 
               on p.person_name = imported_marathon_person_list.p_name
    
            join marathon m 
               on m.marathon_name = imported_marathon_person_list.m_name