簡體   English   中英

更新中介表最佳實踐PHP,MySQL

[英]Updating the intermediary table Best practice PHP, MySQL

假設我在兩張桌子的學生和科目之間有多對多關系。 因此,我們創建了一個中間表來映射數據。 可以說這是students_subjects。 students_subjects表具有2列,分別是student_id和subject_id。

+------------+--------------+
| student_id | student_name |
+------------+--------------+
|            |              |
+------------+--------------+

+------------+--------------+
| subject_id | subject_name |
+------------+--------------+
|            |              |
+------------+--------------+

+------------+------------+
| student_id | subject_id |
+------------+------------+
|            |            |
+------------+------------+

直到最近一段時間,students_subjects(學生選擇學科)有了更新,我所做的是刪除所有學生插入了新學科的學科。

+------------+------------+----------+
| student_id | subject_id | selected |
+------------+------------+----------+
| 1          | 2          | 1        |
+------------+------------+----------+
| 1          | 2          | 0        |
+------------+------------+----------+

但是最近我選擇了在此中介表中添加新列。 因此,如果學生選擇了新的科目並取消選擇了一些舊的科目,那么我為新科目添加了活動,而對取消選擇科目則添加了非活動。 (我在PHP中通過獲取新選擇的科目和先前擁有的科目來進行此操作。然后將兩者進行比較。當學生選擇科目時,我會檢查該學生具有的所有主題([活動和非活動中]。如果新選擇的科目先前未處於活動狀態)我將它們激活並添加新的主題。)

最佳做法是什么? 我有更好的方法來實現這一目標嗎?

我確實認為您的第一種方法(刪除所有關聯的行並插入新條目)要簡單得多。

如果仍然希望具有selected字段,一種簡單的方法是創建唯一的復合索引並使用INSERT ... ON DUPLICATE KEY UPDATE 這也可以防止意外插入相同的user_idsubject_id對。 首先創建索引:

ALTER TABLE `students_subjects` ADD UNIQUE `unique_student_subject`(`student_id`, `subject_id`);

然后,只需將學生selected字段更新為0然后插入學生選擇的主題即可。 使用PDO示例:

$studentId = 1;
$newlySelectedSubjects[] = ['subject_id' => 3];
$newlySelectedSubjects[] = ['subject_id' => 4];

$db = new PDO("connection string here", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$db->beginTransaction();

try{
    $qry = 'UPDATE students_subjects SET selected = 0 WHERE student_id = :studentId';

    $stmt = $db->prepare($qry);
    $stmt->execute(['studentId' => $studentId]);

    $insertQry = 'INSERT INTO students_subjects (student_id, subject_id, selected)' 
                 .'VALUES (:studentId, :subjectId, 1) '
                 .'ON DUPLICATE KEY UPDATE '
                 .'selected = 1';
    $insertStmt = $db->prepare($insertQry);

    foreach ($newlySelectedSubjects as $subject) {

        $params = ['studentId' => $studentId, 'subjectId' => $subject['subject_id']];
        $insertStmt->execute($params);
    }
    $db->commit();
} catch (PDOException $e) {
    //do something with exception
    $db->rollBack();
}

將會發生的情況是,如果表中已經存在具有student_id = 1subject_id = 3的學生,則selected字段將設置為1 ,否則將不插入新記錄。

如果您需要跟蹤用戶主題選擇和取消選擇,我建議實施某種審計跟蹤,並讓students_subjects只保留學生和主題之間的關系。 借助mysql TRIGGER可以更容易。審核跟蹤表的簡化示例:

+------------+------------+----------+---------------------+
| student_id | subject_id | action   | action_datetime     |
+------------+------------+----------+---------------------+
| 1          | 2          | remove   | 2018-01-01 00:01:23 |
+------------+------------+----------+---------------------+
| 1          | 4          | add      | 2018-01-01 01:07:45 |
+------------+------------+----------+---------------------+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM