Я думаю, что ваш первый подход (удаление всех связанных строк и вставка новых записей) намного проще.
Если все еще нужно иметь поле selected
, простым способом было бы создать уникальный составной индекс и использовать INSERT ... ON DUPLICATE KEY UPDATE
. Это также может предотвратить случайную вставку одной и той же пары user_id
и subject_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
= 1
и subject_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 |
+------------+------------+----------+---------------------+