Как запретить одному и тому же пользователю обновлять свою запись в MySQL? - PullRequest
1 голос
/ 06 апреля 2020

Подробности:

У меня есть 3 таблицы:

create table request (
    id int not null primary key auto_increment,
    date_requested timestamp,
    user_id int,
    filename varchar(255),
    status enum('New','Verified','Rejected') not null default 'New',
    foreign key(user_id) references users(id)
);

create table users (
    id int not null primary key auto_increment,
    username varchar(50) not null,
    password varchar(255) not null
);

create table verify (
    id int not null primary key auto_increment,
    user_id int,
    request_id int,
    created timestamp,
    status enum('Verified','Rejected') not null,
    foreign key(request_id) references request(id)
);

Вот пример данных для таблицы запросов: (Извините, не был уверен, как предоставить Пример с заголовками ниже).

id|    date_requested|   user_id|              filename|                status|
1 |  2020-04-06 13:33:51    3     C:\Users\LV98\Desktop\123 321.jpg    New

А вот и пользователи:

id   username   password
1      test1      123
2      test2      123@#
3      test1      123321

Далее отметим этот документ. У меня есть этот запрос, чтобы добавить запись в таблицу verify. Вы можете видеть ссылки user_id и request_id

insert into verify (user_id, request_id, created, status, comments) values (3,1,now(), 'Rejected', 'Tester');

Проблема:

Но запрос выше не должен быть разрешен, потому что пользователь помечает их собственная запись. Как это можно предотвратить? Как я могу запросить это по-другому?

1 Ответ

0 голосов
/ 06 апреля 2020

Вы можете применить его на уровне базы данных, изменив первичный ключ (или использовать другой уникальный ключ), включив в него также идентификатор пользователя и ограничение 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...