我有这些表格:
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)
)
人员表由一个包含大约130,000行的CSV填充。此CSV包含每个人的唯一varchar(40)和一些其他人员数据。 CSV中没有ID。
对于每次马拉松比赛,我都会获得一张包含1k-3k人名单的CSV。 CSV基本上只包含person_key
值列表,显示哪些人参与了特定的马拉松比赛。
将数据导入person_marathon
表以维持FK关系的最佳方法是什么?
这些是我目前可以想到的想法:
将person_id + person_key
信息从MySQL中拉出并合并PHP中的person_marathon
数据以获取person_id
,然后插入person_marathon
表
使用临时表进行插入...但这是为了工作而我被要求永远不要在此特定数据库中使用临时表
根本不要使用person_id
而只使用person_key
字段,但我必须加入varchar(40)
,这通常不是一件好事< / p>
或者,对于插入,使它看起来像这样(我必须插入<hr>
否则它不会将整个插入格式化为代码):
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
该插入的问题是,要在PHP中构建它,imported_marathon_person_list
将是巨大的,因为它可能很容易成为30,000 select union
项。不过,我不知道怎么做。
答案 0 :(得分:2)
我处理过类似的数据转换问题,但规模较小。如果我正确地理解你的问题(我不确定),听起来像你的情况具有挑战性的细节是这样的:你试图在同一步骤中做两件事:
简而言之,我会尽一切可能避免在同一步骤中完成这两件事。将其分解为这两个步骤 - 首先以可容忍的形式导入所有数据,然后再对其进行优化。 Mysql是进行此类转换的良好环境,因为当您将数据导入到人员和马拉松表中时,会为您设置ID。
第1步:导入数据
完成导入数据后,您有三个表: *人 - 你有丑陋的人员钥匙,以及新生成的person_id,以及任何其他领域 *马拉松 - 此时你应该有一个marathon_id,对吗?要么是新生成的,要么是你从旧系统中带来的数字。 * persons_marathons - 此表应填写marathon_id&amp;指向马拉松表中的正确行,对吧?你也有personkey(丑陋但存在)和person_id(仍然是null)。
步骤2:使用personkey为关联表中的每一行填写person_id
然后你要么直接使用Mysql,要么写一个简单的PHP脚本,为persons_marathons表中的每一行填写person_id。如果我无法让mysql直接执行此操作,我会经常编写一个php脚本来一次处理一行。这里的步骤很简单:
你可以告诉PHP重复这个100次然后结束脚本,或1000次,如果你不断出现超时问题或类似taht。
此转换涉及大量查找,但每次查找只需要一行。这很有吸引力,因为在任何时候你都不需要让mysql(或PHP)“将整个数据集保持在其头部”。
此时,您的关联表应该为每一行填写person_id。删除personkey列现在是安全的,瞧,你有高效的外键。