-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
  • attachmentName - varchar
  • ファイルタイプ - varchar
  • コンテンツ - ミディアムブロブ
  • コード - 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 行に配置するのが最善の方法ですか? 私がはっきりしていない場合は申し訳ありません。

これを 1 つのテーブルにして、この問題を回避することに欠点はありますか?

4

2 に答える 2

2

トランザクションを使用して、挿入全体がアトミック (1 つの挿入) として処理されるようにすることをお勧めします。これにより、クエリの 1 つが失敗した場合でも、データが不正な状態にならないようにデータが保護されます。

あなたのコードは、使用している 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

最初に $emailFrom がユーザー テーブルに存在するかどうかを確認し、ユーザー ID を $userid に取得します。存在しない場合は挿入し、新しいユーザー ID を $userid に取得します。

次に、添付ファイルに挿入し、$attachmentID で新しい attachmentid ストアを取得します。

次に、最後にメールに挿入します。

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

次に、外部キーが正しく設定されます。

于 2012-04-14T02:09:49.473 に答える