【问题标题】:Relational table with perl dbi module带有 perl dbi 模块的关系表
【发布时间】:2013-03-13 08:45:24
【问题描述】:

我想在这两个表之间用 perl 创建一个关系表,并在其中插入数据:

$create_query = qq{
    create table article(
        id_article int(10) auto_increment NOT NULL,
        url MEDIUMTEXT COLLATE utf8_general_ci,
        html_extr_text TEXT COLLATE utf8_general_ci,
        concord_file TEXT COLLATE utf8_general_ci,
        sys_time VARCHAR(50),
        primary key (id_article)
        )
};
$dbh->do($create_query);

 $create_query = qq{
     create table event(
         id_event int(10) auto_increment NOT NULL,
         event MEDIUMTEXT COLLATE utf8_general_ci,
         primary key (id_event)
         )
};
$dbh->do($create_query);

现在关系表如下所示:

$create_query = qq{
    create table article_event_index(
        id_article int(10) NOT NULL,
        id_event int(10) NOT NULL,
        primary key (id_article, id_event),
        foreign key (id_article) references article (id_article),
        foreign key (id_event) references event (id_event)
        )
};
$dbh->do($create_query);

有人知道要填充“article_event_index”表的 perl 语句应该是什么吗? 对于其他表,我为每个表使用数组,它看起来像这样:

my $i_event;
my $id_event = 0;
my @event_index;
for ($i_event = 0; $i_event < @event_prepare; $i_event++){
    $dbh->do("
        INSERT INTO `event`(`id_event`, `event`)
        VALUES ('$id_event', '$event_prepare[$i_event]')
        ") || die $dbh->errstr;
    push @event_index, $i_event;
}
$id_event++;

在这种情况下,'id_event' 是由 $id_event 的增量生成的。如果我想在索引表中重用这个 id,这是一个好习惯吗?

【问题讨论】:

    标签: perl foreign-keys dbi


    【解决方案1】:

    除了 Dave Sherohman 的回复之外,您的代码中还有一些 cmets:

    您应该考虑为您的插入使用准备好的语句:

    my $sth = $dbh->prepare("INSERT INTO `event`(`id_event`, `event`) VALUES (?,?)");
    

    然后在您的循环中,您可以为需要插入的每一行执行此操作:

    $sth->execute($id_event, $event_prepare[$i_event]);
    

    这更简单(它为您处理引用)、更安全(防止 SQL 注入)和更快。

    此外,您永远不需要为了遍历数组而使用 C 风格的 for 循环。您可以使用以下形式之一:

    for my $i_event (0..$#event_prepare){
        #if you need the array index.
    }
    
    for my $event (@event_prepare) {
        #if you don't need the array index.
    }
    

    另外,这只是一个偏好,但我不喜欢 { ... } 作为字符串分隔符,因为它们看起来太像代码块了。

    【讨论】:

      【解决方案2】:

      由于id_event 字段定义为auto_increment,您可以让数据库为您生成 id 值,这是我通常这样做以避免任何竞争条件的方式。 (即,如果两个单独的用户/进程尝试同时插入行并且都生成相同的 id 值,则第二个提交的用户/进程将失败。)

      插入一行后,如果需要在另一个表中用作外键,可以使用DBI的last_insert_id方法获取新行的自动生成的id值:

      my $id = $dbh->last_insert_id(undef, undef, 'event', 'id_event');
      

      【讨论】:

      • 是的,使用 'last_insert_id' 方法我得到了 id 的列表。但是,如何使“文章”和“事件”之间的关系成为一对多的关系?因为一篇文章,可能有多个事件。所以它会是:1 - 1, 1 - 2, 2 - 3, 2 - 4, 2 - 5...等等。第一个数字是文章,第二个数字是事件。再次感谢
      • 一对多关系在此处由您填充表格的方式定义。如果在您的映射表上,您插入相同的偶数 ID、多个文章 ID(这是您的映射表定义允许的),那么您就有一对多的关系。我觉得您正在寻找一种“神奇”的方式来创建一对多关系,而无需处理 idx 和交叉表。你应该看看DBIx::Class,它可以让你这样做(但它的API比DBI更复杂)。
      猜你喜欢
      • 2011-03-26
      • 2016-11-01
      • 2012-10-28
      • 1970-01-01
      • 2019-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多