是否可以禁止对MySQL行进行修改?

时间:2019-04-17 19:45:55

标签: mysql row

我有一个MySQL表,该表存储一些我不想被任何人修改的数据。这意味着即使是数据库管理员也不应对其进行修改。有什么办法可以禁止包括数据库管理员在内的所有人修改表行?

我研究了这可以通过读/写锁部分实现。但是,仍将允许数据库管理员使用持有锁的用户名登录并加以利用。

我的目标是禁止所有人(包括数据库管理员)对表记录进行修改。我有什么办法可以使用MySQL实现此目标吗?

2 个答案:

答案 0 :(得分:0)

管理员帐户始终完全控制服务器上的数据库。即使您对表具有revoke权限,管理员也可以自己grant权限。从常识的角度来看,这是有道理的。如果您确实想更新该表中的一行,该怎么办?核对整个服务器并重新插入?

您能做的最好的就是设置一些审核。如果可以对表进行备份,并定期将表与备份进行比较,则这是一种可能的方法。确保将备份存储在管理员无法访问的位置。当然,还有其他各种各样的潜在问题,所以这不是很理想。

如果您愿意切换到MariaDB,则可以利用System-Versioned Tables。我通常不会建议“尝试其他RDBMS”,但是MariaDB是MySQL的一个分支,因此过渡可能不会像切换到Oracle那样痛苦。

答案 1 :(得分:0)

如前所述,很难将事情限制为管理员,因为它几乎可以完成所有事情。

您可以创建一个阻止更新的触发器。我有2种解决方案,其中包含2种不同的触发器

示例1

此版本不会发送错误,但是对模式修改很明智。它还会影响“ 0行”

-- Table
CREATE TABLE not_updatable(
  id int unsigned not null auto_increment primary key,
  data varchar(50)
);

-- Trigger
DELIMITER $$

CREATE TRIGGER not_updatable_after_update
  BEFORE UPDATE
  ON not_updatable
  FOR EACH ROW
  BEGIN
    SET NEW.id=OLD.id, NEW.data=OLD.data;
  END$$

DELIMITER ;

结果:

mariadb@localhost:test> CREATE TABLE not_updatable(
                          id int unsigned not null auto_increment primary key,
                          data varchar(50)
                        );
Query OK, 0 rows affected
Time: 0.236s
mariadb@localhost:test> CREATE TRIGGER not_updatable_after_update
                    ->    BEFORE UPDATE
                    ->    ON not_updatable
                    ->    FOR EACH ROW
                    ->    BEGIN
                    ->      SET NEW.id=OLD.id, NEW.data=OLD.data;
                    ->    END;
Query OK, 0 rows affected
Time: 0.070s
mariadb@localhost:test> insert into not_updatable(data) values ('test 1'), ('test 2');
Query OK, 2 rows affected
Time: 0.043s
mariadb@localhost:test> select * from not_updatable;
+------+--------+
| id   | data   |
|------+--------|
| 1    | test 1 |
| 2    | test 2 |
+------+--------+
2 rows in set
Time: 0.004s
mariadb@localhost:test> update not_updatable set data = 'test 3' where id = 1;
Query OK, 0 rows affected
Time: 0.001s
mariadb@localhost:test> select * from not_updatable;
+------+--------+
| id   | data   |
|------+--------|
| 1    | test 1 |
| 2    | test 2 |
+------+--------+
2 rows in set
Time: 0.003s

示例2

这会引发错误,因此对于攻击者而言更可见

-- Table
CREATE TABLE not_updatable(
  id int unsigned not null auto_increment primary key,
  data varchar(50)
);

-- Trigger
DELIMITER $$

CREATE TRIGGER not_updatable_after_update
  BEFORE UPDATE
  ON not_updatable
  FOR EACH ROW
  BEGIN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Don''t try to cheat !';
  END$$

DELIMITER ;

结果:

mariadb srumeu@localhost:test> drop trigger not_updatable_after_update;
Query OK, 0 rows affected
Time: 0.000s
mariadb srumeu@localhost:test> CREATE TRIGGER not_updatable_after_update
                            ->   BEFORE UPDATE
                            ->   ON not_updatable
                            ->   FOR EACH ROW
                            ->   BEGIN
                            ->     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Don''t try to cheat !';
                            ->   END;
Query OK, 0 rows affected
Time: 0.078s
mariadb srumeu@localhost:test> update not_updatable set data = 'test 3' where id = 1;
(1644, "Don't try to cheat !")
mariadb srumeu@localhost:test> select * from not_updatable;
+------+--------+
| id   | data   |
|------+--------|
| 1    | test 1 |
| 2    | test 2 |
+------+--------+
2 rows in set
Time: 0.014s