是否有任何工作方式将MySQL行设置为READ-ONLY?

问题描述 投票:2回答:3

我在这里阅读了所有主题,并没有找到任何简单而有效的解决方案。所以我在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;

只有错误。谢谢。

mysql mariadb
3个回答
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表中。


0
投票

MySQL没有每行访问控制。这样做的方法是使整个表只读,但创建一个具有写权限的特殊用户。然后编写一个更新表的存储过程,并使其由该用户拥有。存储过程可以检查entry_id = 12345是否执行更新。

SELECT ... FOR UPDATE不会阻止写行,它只是在事务持续期间锁定它。在事务完成之前,其他事务将被阻止,但随后他们将能够更新该行。


0
投票

您可以将访问数据库的用户的访问权限更改为仅具有读取权限

或者您可以创建另一个列,将其称为“已锁定”,并在查询中添加一个参数,以便不更新任何具有锁定值的行。

将锁定字段设置为日期时间,默认值为null。这样,您可以选择已锁定的值并按锁定日期创建订单。您还可以将另一个字段添加为locked_by并附加用户ID。

或者,您可以创建一个锁定的表并使用连接 - 如果被锁定的数据不是标准的,我会选择这个

例如:

  UPDATE 
   date = NOW()
  FROM table
  WHERE id = 123 AND locked IS NULL
© www.soinside.com 2019 - 2024. All rights reserved.