【问题标题】:Inserting "large" amounts of data into MySQL and the benefits of using a foreign key将“大量”数据插入 MySQL 以及使用外键的好处
【发布时间】:2013-07-22 23:02:36
【问题描述】:

我不确定如何存储或插入这些数据。我正在使用 PHP 和 MySQL。

假设我们正在尝试跟踪参加马拉松比赛的人(例如慢跑或其他)。到目前为止,我有一个 Person 表,其中包含我的所有个人信息。每个人恰好与一个唯一的 varchar(40) 键相关联。有一个马拉松信息表(Marathon)。我以 CSV 格式接收大约 130,000 行的人员数据并将其导入数据库。

所以 - 现在的问题是……我该如何处理 Person 和 Marathon 之间的关联?对于每个 Marathon,我都会获得需要导入的大量参与者列表(通过唯一的 varchar 键)。所以......如果我走外键路线,似乎插入会非常繁重,为该人查找适当的外键。我什至不确定我会如何写那个插入......我猜它看起来像这样:

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 

一次处理的马拉松并不多。不过有很多人。

--> 我是否应该给此人一个 ID 并要求所有外键?还是只使用唯一的 varchar(40) 作为真正的表键?但是后来我必须在 varchar 上加入表,这很糟糕。一场马拉松可以有 1k 到 30k 的参与者。

--> 或者,我可以从数据库中选择人员信息和马拉松信息,然后将其与 PHP 中的 marathon_person 数据连接起来,然后再将其发送到 MySQL。

--> 或者,我想,也许可以创建一个临时表,然后加入数据库,然后插入(通过 PHP)?已经强烈建议我不要使用临时表(这是一项工作,这不是我的数据库)。

编辑:我不确定要使用什么架构,因为我不确定我是否应该使用外键(整篇文章的目的是回答这个问题)但是基本设计类似于......

create table person ( 
    person_id int unisgned auto_incrememnt, 
    person_key varchar(40) not null, 
    primary key (person_id),
    constraint uc_person_key unique (person_key)
)

create table marathon (
    marathon_id int unisgned auto_incrememnt, 
    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),
    constraint uc_person_marathon unique (person_id, marathon_id), 
    foreign key person_id references person (person_id),
    foreign key marathon_id references marathon (marathon_id)
)

我将很快重复实际问题....如果我选择为person 使用外键,我如何以有效的方式导入带有person_id 的所有person_marathon 数据?我上面包含的插入语句是我最好的猜测......

person 数据以大约 130,000 行的 CSV 格式出现,因此可以直接导入到 person 表中。个人数据带有每个人的唯一 varchar(40)。

person_marathon 数据以 CSV 格式出现在每个马拉松比赛中,作为一个包含 1,000 到 30,000 个唯一 varchar(40) 的列表,代表参加该马拉松比赛的每个人。

总结:我正在使用 PHP。那么,如果我使用外键,那么编写 person_marathon 数据的插入/导入的最佳方法是什么?我必须像上面的插入语句那样做还是有更好的方法?

【问题讨论】:

  • 发布您正在使用的当前数据库架构。

标签: php mysql insert


【解决方案1】:

这是多对多的关系,一个人可以参加很多场马拉松,一场马拉松可以参加很多人。您需要在数据模型中添加额外的表来跟踪这种关系,例如:

CREATE TABLE persons_marathons(
  personID int FOREIGN KEY REFERENCES Persons(P_Id),
  marathonID int FOREIGN KEY REFERENCES Marathons(M_Id)
)

此表使用外键约束。外键约束防止插入错误数据(例如,当 Persons 表中没有这样的 id 时,您不能插入 personID = 123 的行),它还可以防止删除会破坏表之间的链接(例如,您不能删除当 person_marathon 表中存在具有此 personID 的记录时,人 X)。

如果此表包含以下行:

personID  | MarathonID
----------+-----------
    2     |  3
    3     |  3
    2     |  8
    3     |  8

表示2号和3号都参加了3号和8号马拉松

【讨论】:

  • 我无意粗鲁,但我认为您不理解我的帖子/问题...我编写的示例插入语句显示了一个包含 person_id 和 marathon_id 的 person_marathon 表。问题不在于如何使用外键。
猜你喜欢
  • 2013-03-29
  • 2013-07-21
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多