我想要的是在mySQL表中插入数据,但我无法找到从一行建立关系的方法
假设我有一个文件 file.tab 它包含
中的数据parent_1 parent_details_1 child_1.1 child_details_1.1 child_1.2 child_details_1.2
parent_2 parent_details_2 child_2.1 child_details_2.1
parent_3 parent_details_3 child_3.1 child_details_3.1 child_3.2 child_details_3.2 child_3.3 child_details_3.3
我想实现的是在两个表中插入数据,例如
parent_table
+---+-----------+-------------------+
|id | name | details |
+---+-----------+-------------------+
| 1 | parent_1 | parent_details_1 |
| 2 | parent_2 | parent_details_2 |
| 3 | parent_3 | parent_details_3 |
+---+-----------+-------------------+
child_table
+---+-----+-----------+-------------------+
|id | pid | name | details |
+---+-----+-----------+-------------------+
| 1 | 1 | child_1.1 | child_details_1.1 |
| 2 | 1 | child_1.2 | child_details_1.2 |
| 3 | 2 | child_2.1 | child_details_2.1 |
| 4 | 3 | child_3.1 | child_details_3.1 |
| 5 | 3 | child_3.2 | child_details_3.2 |
| 6 | 3 | child_3.3 | child_details_3.3 |
+---+-----+-----------+-------------------+
前两个列适用于父母,在那两二列属于孩子,但我不知道父母有多少个孩子。
我试图以这种方式加载文件。
LOAD DATA INFILE '/tmp/file.tab INTO TABLE ...
但是我接下来我不知道。
非常好心地帮助我。
创建一个带有许多列的表(Staging
)。有parent_id
的空(NULL
)列,以及儿童的ID。
希望"短"线将在LOAD DATA
期间将零件的nulls放在丢失的儿童列中。
INSERT .. SELECT ..
将parent
和parent_detail
放入Parents
表中。将ids
从Parents
拉回Staging.parent_id
。这些SQL的详细信息在http://mysql.rjweb.org/doc.php/staging_table#normalization
现在为每一组"儿童"列集类似的事情:child1
和child1_detail
(可能为null对)和当前的null child1_id
。同上儿童2*等。请注意,当填充Children
表时,您已经有parent_id
可用。
这是完成任务的全sql方式。它只是比写perl/php/java/vb/任何执行任务的代码的混乱少了。
假设孩子和父母都是我创建一个人桌的人,只有id_parent是可选的。
CREATE TABLE person (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) DEFAULT NULL,
details varchar(255) DEFAULT NULL,
id_parent1 int(11) DEFAULT NULL,
id_parent2 int(11) DEFAULT NULL,
PRIMARY KEY (id)
);
如何加载数据取决于您喜欢的语言。Load data infile
需要一个静态结果表。
您拥有的行数可能会有所不同,您需要将每一行几乎以单列导入。然后,您可以使用存储过程进行迭代:
- 查看
cursors
,以查看如何在此类单列登台表的每一行上迭代。 - 在选项卡定界符上使用
replace
您可以找出每一行中的列数。 - 使用
while
循环,您可以首先开始进口孩子,然后再进口父母。
公平地说,这将是一个相当复杂的存储过程,对于初学者来说,可能很难编写。如果您熟悉任何编程语言及其连接到MySQL的手段,则可以更优雅地做到这一点。
如果解决方案不需要全部,则我发现预处理通常更简单。在这种情况下
这是使用Perl
进行预处理的一种方法my ( $parent_id, $child_id ) = ( 0, 0 );
my ( @parent_table, @child_table );
while (<>) { # for each line of input
chomp;
# split on tabs
my ( $parent_name, $parent_detail, @child_id_detail_pairs ) = split /t/;
# create a row and parent_id for the parent table
push @parent_table, [ ++$parent_id, $parent_name, $parent_detail ];
while (@child_id_detail_pairs) { # while we have child names & details
# remove a name and details
my $child_name = shift @child_id_detail_pairs;
my $child_details = shift @child_id_detail_pairs;
# create a row and child_id for the child table
push @child_table, [ ++$child_id, $parent_id, $child_name, $child_details ];
}
}
# write this to one file to load into the parent table
print "parent_tablen";
for my $row (@parent_table) {
print join( "t", @$row ), "n";
}
# write this to one file to load into the child table
print "child_tablen";
for my $row (@child_table) {
print join( "t", @$row ), "n";
}