Вы можете применить его на уровне базы данных, изменив первичный ключ (или использовать другой уникальный ключ), включив в него также идентификатор пользователя и ограничение CHECK
в таблице проверки, которая сравнивает идентификатор пользователя верификатора и запрос идентификатор пользователя.
Сначала вы создаете таблицу request
следующим образом:
CREATE TABLE request (
id int NOT NULL AUTO_INCREMENT,
user_id INT NOT NULL,
dummy VARCHAR(100), -- just for testing
PRIMARY KEY (id, user_id), -- two column primary key
FOREIGN KEY (user_id) REFERENCES users(id)
);
Теперь таблица verify
должна использовать первичный ключ из двух столбцов в качестве внешнего ключа, в противном случае ссылка это невозможно. Поскольку запрашиваемый идентификатор пользователя находится внутри таблицы verify
, вы можете добавить CHECK
, который гарантирует, что вы не можете проверить себя:
CREATE TABLE verify (
id int NOT NULL AUTO_INCREMENT,
verifier_user_id INT NOT NULL,
request_id INT NOT NULL,
request_user_id INT NOT NULL,
dummy VARCHAR(100), -- again, just for testing
PRIMARY KEY (id),
FOREIGN KEY (verifier_user_id) REFERENCES users(id),
FOREIGN KEY (request_id, request_user_id) REFERENCES request(id, user_id),
CHECK (verifier_user_id != request_user_id)
);
Поскольку verifier_user_id
и request_user_id
не могут быть одинаковыми, и вы должен включать весь внешний ключ из таблицы request
, вы больше не можете проверить себя:
mysql> SELECT * FROM users;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | first | user |
| 2 | second | user |
+----+----------+----------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM request;
+----+---------+-------+
| id | user_id | dummy |
+----+---------+-------+
| 1 | 1 | test |
+----+---------+-------+
1 row in set (0.00 sec)
mysql> INSERT INTO verify (verifier_user_id, request_id, request_user_id, dummy) VALUES (2, 1, 1, 'test a');
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO verify (verifier_user_id, request_id, request_user_id, dummy) VALUES (1, 1, 1, 'test a');
ERROR 3819 (HY000): Check constraint 'verify_chk_1' is violated.