这比我想象的要棘手;首先,我按照 acfrancis 在评论中的建议使用触发器进行了调查,但是在 MySQL 触发器中,您无法更新触发器所在的表 - 因此 INSERT 触发器和 UPDATE 触发器都已退出。如果您的 DBMS 支持它,这将是一种可能性。
所以,你留下了约束概念,你需要考虑你在限制什么。如果您想确保一个人没有被记录为在多个浴室中,那么您可以添加相关约束,如下所示:
mysql> DROP TABLE IF EXISTS bathroom_occupant;
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE TABLE bathroom_occupant (bathroom_id INT, person_id INT);
Query OK, 0 rows affected (0.12 sec)
mysql> ALTER TABLE bathroom_occupant ADD CONSTRAINT
-> UNIQUE INDEX person_id (person_id);
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
然后人 1 进入浴室 1,人 2 进入浴室 2
mysql> INSERT INTO bathroom_occupant (bathroom_id, person_id) VALUES (1, 1);
Query OK, 1 row affected (0.03 sec)
mysql> INSERT INTO bathroom_occupant (bathroom_id, person_id) VALUES (2, 2);
Query OK, 1 row affected (0.01 sec)
然后,当您想要更新某人所在的浴室时,您可以使用 INSERT 查询并添加 ON DUPLICATE KEY UPDATE 语句。下面的人 1 移动到浴室 2
mysql> INSERT INTO bathroom_occupant (bathroom_id, person_id) VALUES (2, 1)
-> ON DUPLICATE KEY UPDATE bathroom_id = VALUES(bathroom_id);
Query OK, 2 rows affected (0.02 sec)
mysql> SELECT * FROM bathroom_occupant;
+-------------+-----------+
| bathroom_id | person_id |
+-------------+-----------+
| 2 | 1 |
| 2 | 2 |
+-------------+-----------+
2 rows in set (0.00 sec)
如您所见,浴室 2 有两条记录 - 因为我们的限制是只有一个人在不超过一间浴室。在现实世界中,这没关系——两个人可以进入同一个浴室。而且我认为它适用于您的另一个示例 - 学生注册到同一班级的两个部分(许多学生可以在同一部分,但一个学生只能在一个部分)。
但是,您将您的表命名为浴室占用者——对我来说,这个名称表明该表显示了谁是每个浴室的居住者——也许您希望每个浴室只有一个居住者。如果这是你所需要的——即你有一个限制,每个人只能在一个浴室里,每个浴室只能容纳一个人——那么这变得更加困难。我认为当人 1 进入时将人 2 从浴室 2 踢出的逻辑超出了 MySQL 在内部可以做的事情。如果要在表上添加另一个约束,这次是针对浴室 ID,则插入将失败,因为 ON DUPLICATE KEY UPDATE 语句仅修复了一条记录的问题。
如果您很高兴多个人可以在一个浴室里,那么您可以在想要将某人放入浴室时使用以下代码:
INSERT INTO bathroom_occupant (bathroom_id, person_id)
VALUES ('$new_bathroom_id', '$person_id')
ON DUPLICATE KEY UPDATE bathroom_id = VALUES(bathroom_id);
这是一个查询 - 根据要求。:-)