我在这里阅读了所有线程,却没有找到解决我的问题的任何简单有效的解决方案。所以我在php脚本上运行网站,该脚本在10.1.37-MariaDB上使用DB。
我那里有1张桌子,我只需要设置几行(从90k开始)为只读。不再由php脚本更新或删除。
所有这些行都有带有数字值的唯一entry_id
,可以说entry_id = 12345
。
在需要的表中,我也有这个:
SELECT * FROM `cb_aggregator_content` ORDER BY `model_last_checked` ASC
试图添加:
SELECT * FROM `cb_aggregator_content` WHERE `entry_id`=12345 FOR UPDATE;
仅获得错误。 谢谢。
答案 0 :(得分:4)
这是一个潜在的解决方案:
创建一个表来存储您要为只读的主键值:
CREATE TABLE cb_aggregator_content_readonly (
entry_id INT PRIMARY KEY
);
INSERT INTO cb_aggregator_content_readonly SET entry_id = 12345;
如果您尝试更新或删除条目ID应该是只读的行,则使触发器引发错误:
DELIMITER ;;
CREATE TRIGGER no_upd_content BEFORE UPDATE ON cb_aggregator_content
FOR EACH ROW BEGIN
IF EXISTS(SELECT * FROM cb_aggregator_content_readonly WHERE entry_id = OLD.entry_id) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Please do not update entry ';
END IF;
END;;
CREATE TRIGGER no_del_content BEFORE DELETE ON cb_aggregator_content
FOR EACH ROW BEGIN
IF EXISTS(SELECT * FROM cb_aggregator_content_readonly WHERE entry_id = OLD.entry_id) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Please do not delete entry';
END IF;
END;;
DELIMITER ;
现在,它应该阻止您更新或删除要保留的行:
mysql> delete from cb_aggregator_content where entry_id = 123;
Query OK, 1 row affected (0.02 sec)
mysql> delete from cb_aggregator_content where entry_id = 12345;
ERROR 1644 (45000): Please do not delete entry
如果要向要保留的条目集添加更多entry_id,只需在cb_aggregator_content_readonly表中插入更多值即可。
答案 1 :(得分:0)
MySQL没有按行访问控制。这样做的方法是使整个表为只读,但创建一个对其具有写权限的特殊用户。然后编写一个存储过程来更新表,并使该表归该用户所有。该存储过程可以检查是否entry_id = 12345
并且不执行更新。
SELECT ... FOR UPDATE
不会阻止写行,它只是在事务期间将其锁定。其他事务将仅被阻塞,直到事务完成为止,但随后它们将能够更新该行。
答案 2 :(得分:0)
您可以将访问数据库的用户的访问权限更改为仅具有读取权限
或者您可以创建另一个称为“已锁定”的列,并在查询中添加一个参数,以不使用已锁定的值更新任何行。
将锁定字段设置为日期时间,默认值为null。这样,您可以选择锁定的值并按锁定的日期创建订单。您还可以将另一个字段添加为locked_by,并附加一个用户ID。
或者,您可以创建一个锁定表并使用联接-如果要锁定的数据不是标准数据,我会选择
例如:
UPDATE
date = NOW()
FROM table
WHERE id = 123 AND locked IS NULL