我目前正在完成一个PHP脚本,该脚本解析电子邮件并将其插入到结构如下的数据库表中 -
用户表
- 用户ID - 整数 - auto_increment - PK
- 电子邮件 - 瓦尔查尔
电子邮件表
- 电子邮件ID - 整数 - auto_increment - PK
- 用户标识 - 整数 - FK
- 附件 ID - 整数 - FK
- 身体 - 瓦尔查尔
- 主题 - 瓦尔查尔
附件表
- 附件 ID - 整数 - auto_increment - PK
- 附件名称 - 瓦尔查尔
- 文件类型 - 瓦尔查尔
- 内容 - 中等斑点
- 代码 - 瓦尔查尔
问题是,一旦我解析了电子邮件,如何确保我的外键关系是正确的?我最初的方法只是执行:
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 行中是最佳方法吗?对不起,如果我不清楚。
将其合并为一个表并避免此问题是否有任何缺点?
我建议使用事务,确保将整个插入视为原子(一个插入)。这可以保护数据,以防其中一个查询失败,数据最终不会处于格式错误状态。
你的代码没有逃脱你正在使用的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 调用的更多信息:
绑定参数
开始事务
犯
反转
首先检查用户表中是否存在$emailFrom,将用户 ID 放入$userid。 如果它不存在,则插入它并将新的用户 ID 放入$userid。
然后插入到附件中,并在$attachmentID中获取新的附件 ID 存储。
最后插入电子邮件:
INSERT INTO emails (userid, attachmentid, subject, body)
values ($userid, $attachmentId, '$subject', '$body');
然后,您的外键将正确设置。