MySQL批量加载多个表,自动递增字段作为外键

时间:2013-07-10 00:08:31

标签: mysql

考虑以下设计示例,其中 FOREST 包含 TREE (s)且 TREE (s) BRANCH (ES)。此外 FLOCK (s)包含 BIRD (s), BIRD (s)可能包含也可能不包含 BRANCH

CREATE TABLE 'FOREST' (
forest_id INT(11) NOT NULL AUTO_INCREMENT,
'name'    VARCHAR(45) NOT NULL,
...
)

CREATE TABLE 'TREE' (
'tree_id'    INT(11) NOT NULL AUTO_INCREMENT,
'forest_id'  INT(11) NOT NULL ,
'tree_loc_x' INT NOT NULL,
'tree_loc_y' INT NOT NULL,
...
CONSTRAINT 'fk_tree_forest'
    FOREIGN KEY ('forest_id' )
    REFERENCES `FOREST` ('forest_id' )
)

CREATE TABLE 'BRANCH' (
'branch_id' INT(11) NOT NULL AUTO_INCREMENT,
'tree_id'   INT(11) NOT NULL,
'br_loc_x'  INT NOT NULL,
'br_loc_y'  INT NOT NULL,
'br_loc_z'  INT NOT NULL,
...
CONSTRAINT 'fk_branch_tree'
   FOREIGN KEY ('tree_id' )
   REFERENCES `TREE` ('tree_id' )
)

CREATE  TABLE 'FLOCK' (
  'flock_id' INT NOT NULL AUTO_INCREMENT ,
  'name'     VARCHAR(45) NOT NULL
...
)

CREATE  TABLE 'BIRD' (
  'bird_id'   INT(11) NOT NULL AUTO_INCREMENT ,
  'flock_id'  INT(11) NOT NULL ,
  'branch_id' INT(11) NULL ,
  'bird_tag'  VARCHAR(45) NOT NULL ,
...
  CONSTRAINT 'fk_bird_flock'
    FOREIGN KEY ('flock_id' )
    REFERENCES 'FLOCK' ('flock_id' )
  CONSTRAINT 'fk_bird_branch'
    FOREIGN KEY ('branch_id' )
    REFERENCES 'BRANCH' ('branch_id' )
 )

我想从C ++应用程序加载批量类型加载(多插入语句或LOAD DATA INFILE)的每个表。

检索数据库的最佳方法是分配auto_increment值,以用作每个后续表加载的外键。

请注意,表格不一定以级联方式加载(即BIRDS将在FLOCKS之后加载,而不是直接在BRANCHES之后加载,因此“LAST_INSERT_ID”在加载BANDDS时不会对BRANCHES有用。)

每个表都有候选自然键,但我试图避免将它们用作主键或外键。

1 个答案:

答案 0 :(得分:0)

当您使用LOAD DATA INFILE(或其他多行INSERT,如INSERT ... SELECT)时,后续对LAST_INSERT_ID()的调用仅返回生成的第一个 id值。但是InnoDB将id分配为一个连续的块,所以如果你插入了1000行,而LAST_INSERT_ID()报告了1234,那么你知道数据加载使用的是id的1234到2233.

(假设auto_incrment_increment = 1;如果不是,那么说你的数据加载将使用下一个连续的1000个id更准确。)

但是如果然后在树之后批量加载分支,则存在不知道每个分支属于哪个树的问题。有些树可能只有一个分支,有些树有六个等等。仅仅因为你有1000棵树和1000个分支,你不一定能假设均匀分布。如果你在树枝上有鸟等,它会变得更加复杂。

最终,将数据批量加载到多个表中并保留所有相应的生成ID是不切实际的。您必须编写代码以逐行循环遍历所有输入文件,并逐行捕获LAST_INSERT_ID()以在相关行中使用。我还没有找到更好的解决方案。

对于鸟类对其各自的分支及其群体都有外键的更复杂的情况,您可以尝试跟踪每个分支的插入ID,并将其映射到自然键,但也许有这么多分支,将映射保留在内存中变得不切实际。在某种程度上,您会发现在插入 分支或鸡群时可以选择插入鸟类,但不能同时插入两者(因为分支和鸡群之间存在多对多关系,您可以假设他们很好地排序)。因此插入鸟类可能涉及为其分支或其群体留下NULL,然后您必须稍后使用UPDATE填写缺失的数据。