-1

我目前正在完成一个 PHP 脚本,该脚本解析电子邮件并将它们插入到结构如下的数据库表中 -

用户表

  • userId - int - auto_increment - PK
  • 电子邮件 - varchar

电子邮件表

  • emailId - int - auto_increment - PK
  • userId - int - FK
  • attachmentId - int - FK
  • 正文 - varchar
  • 主题 - varchar

附件表

  • attachmentId - int - auto_increment - PK
  • 附件名称 - varchar
  • 文件类型 - varchar
  • 内容 - mediumblob
  • 代码 - varchar

我的问题是,一旦我解析了电子邮件,如何确保我的外键关系是正确的?我最初的方法只是执行:

INSERT INTO users (email) values ('$emailFrom');
INSERT INTO emails (subject, body) values ('$subject', '$body');
INSERT INTO attachments (attachmentName, fileType, content, code) values ('$attachmentName', '$fileType', '$content', '$code');

但后来我意识到这不会处理我在电子邮件表中的 FK 关系。单独执行每个查询的最佳方法是重新查询生成的 Id 然后将新 Id 放在相关的 FK 行中吗?对不起,如果我不清楚。

把它做成一张桌子并避免这个问题会有什么缺点吗?

4

2 回答 2

2

我建议使用事务,确保插入的整体被视为原子(一个插入)。这可以保护您的数据,以防如果其中一个查询失败,您的数据最终不会处于格式错误的状态。

您的代码没有避开您正在使用的 API 类型(mysql、mysqli、pdo),但我将使用 PDO(未经测试)给出一个片段:

<?php 
try {

    $dbo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password'); 

    $stmt1 = $dbo->prepare('INSERT INTO users SET email = :email'); 
    $stmt2 = $dbo->prepare('INSERT INTO attachments SET attachment_name = :attachmentName, file_type = :fileType');
    $stmt3 = $dbo->prepare('INSERT INTO emails SET set user_id = :userId, subject = :subject, body = :body, attachment_id = :attachmentId');

    try { 

        $dbo->beginTransaction(); 

        $stmt1->bindParam(':email', $email, PDO::PARAM_STR);
        $stmt->execute();

        $userId = $dbo->lastInsertId();

        $stmt2->bindParam(':attachmentName', $attachmentName, PDO::PARAM_STR);
        $stmt2->bindParam(':fileType', $fileType, PDO::PARAM_STR);
        $stmt2->execute();

        $attachmentId = $dbo->lastInsertId();

        $stmt3->bindParam(':userId', $userId, PDO::PARAM_INT);
        $stmt3->bindParam(':subject', $subject, PDO::PARAM_STR);
        $stmt3->bindParam(':body', $body, PDO::PARAM_STR);
        $stmt3->bindParam(':attachmentId', $attachmentId, PDO::PARAM_INT);
        $stmt3->execute();

        $dbo->commit(); 

    } catch(Exception $e) { 
        $dbo->rollback(); 
        error_log($e->getMessage()); 
    } 
} catch(Exception $e) { 
    error_log($e->getMessage());
} 

?>

您可以使用以下链接阅读有关片段中使用的 API 调用的更多信息:

于 2012-04-14T02:30:08.437 回答
0

首先查看users表中是否存在$emailFrom,将userid取到$userid中。如果它不存在,则插入它并将新的用户 ID 放入 $userid。

然后插入到附件中,并在 $attachmentID 中获取新的附件 ID 存储。

然后最后插入电子邮件:

 INSERT INTO emails (userid, attachmentid, subject, body) 
             values ($userid, $attachmentId, '$subject', '$body');

然后您的外键将被正确设置。

于 2012-04-14T02:09:49.473 回答