mysql - 如何防止同一用户在 MySQL 中更新自己的记录?
问题描述
细节:
我有 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');
问题:
但是上面的查询不应该被允许,因为用户正在标记他们自己的记录。如何防止这种情况?我怎样才能以不同的方式查询它?
解决方案
您可以通过更改主键(或使用不同的唯一键)来在数据库级别上强制执行它,以包括用户 ID 以及CHECK
验证表中比较验证者用户 ID 和请求用户 ID 的约束。
首先,您创建这样的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
表必须使用两列主键作为外键,否则无法引用。因为请求用户 ID 在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
andrequest_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.
推荐阅读
- cordova - Android Studio 3.5:生成签名包没有得到任何结果
- python-3.x - 如何创建通过循环列表中的所有值返回的 Python 模块或类?
- amazon-web-services - 使用多个模型时推荐什么无服务器模式?
- mysql - SQL select s subtr value 和 real value
- java - 从抛出 OutOfMemoryError Apache POI 的 INPUT-STREAM 加载大型 xlsx 文件
- java - 默认构造函数如何初始化字段
- mysql - SQL 查询中的问题(预期输出未出现)
- json - 如何将此 json 展平为 tsv?
- python - Python正则表达式查找给定字符串中存在的模式
- scala - 如何在空的 Spark DataFrame 中添加特殊情况行?