0

考虑以下人为设计的示例,其中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”在相对于 BRANCHES 加载 BIRDS 时没有用)。

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

4

1 回答 1

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 填充缺失的数据。

于 2013-07-10T00:19:44.200 回答