【问题标题】:mariadb state wise where case clause inside viewmariadb statewise where case 子句在视图中
【发布时间】:2021-09-15 13:19:55
【问题描述】:

我在协作表中创建了下面的视图

CREATE VIEW contents(
  id,
  title
)
AS
select 
   mytable.id as id,
   mytable.title as title
from mytable 
where mytable.owner = substring_index(user(), '@', 1);

有什么方法可以在 where 子句中检测 select, insert, update, delete 等视图内部的当前状态?

我希望有下面这样,不知道如何在 mysql/mariadb 中生成等价物

/* during select statement user can see all available data*/
if state == 'select' then
    where 1 = 1 /* can see all data */
else
/* if state is update or delete user is allowed to modify or delete data which for which he/she is owner*/
    where mytable.owner = substring_index(user(), '@', 1);
endif

Here is my sample data

MariaDB [test]> select * from mytable;
+----+-------------------+-------+
| id | title             | owner |
+----+-------------------+-------+
|  1 | created by root   | root  |
|  4 | created by helen  | helen |
|  6 | created by helen1 | helen |
|  7 | 123               | lina |
+----+-------------------+-------+

用户 helen 和 lina 在内容视图上拥有 SELECT, INSERT, UPDATE, DELETE 授权

  • 同样用户helen是普通用户如何授予创建new_database的权限,并继承helen在new_database中创建的任何新表的权限?我不想以管理员身份创建 helen。用户 helen 应该能够在她创建的数据库中创建任意数量的数据库和表。这是否可能?
   new_database
         table1
         table2
         .....
         .....
         tableN

【问题讨论】:

    标签: mysql mariadb mysqladmin mariadb-10.5 mysqladministrator


    【解决方案1】:

    因为check constrants 不能使用user。您可以使用 TRIGGERS 来强制执行约束,例如 fiddle:

    插入:

    CREATE TRIGGER enforce_insert
    BEFORE
    INSERT ON mytable
    FOR EACH ROW
      IF NEW.owner != substring_index(user(), '@', 1) THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'conflict of owner on insert';
      END IF
    

    更新:

    CREATE TRIGGER enforce_update
    BEFORE
    UPDATE ON mytable
    FOR EACH ROW
      IF OLD.owner != substring_index(user(), '@', 1)
         OR NEW.owner != substring_index(user(), '@', 1) THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'conflict of owner on update';
      END IF
    

    删除:

    CREATE TRIGGER enforce_delete
    BEFORE
    DELETE ON mytable
    FOR EACH ROW
      IF OLD.owner != substring_index(user(), '@', 1) THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'conflict of owner on delete';
      END IF
    

    但通常它建议应用程序强制执行数据结构的示意图。

    参考:trigger manual

    【讨论】:

    • 您好,您的解决方案有效,但问题是即使 root 用户也无法更新或删除其他用户数据,例如作为 root 用户 update mytable set title='modify helen data' where id = 4
    • 然而,在 if 子句中几乎没有修改,现在 root 允许修改其他用户数据。您能否建议如何为插入和更新添加自动时间戳,然后如果修改由某些用户修改。比如created_at, modified_at, modified_by字段
    • 完成后,root 和其他管理员用户需要成为每个触发器的逻辑。 DEFAULT 值和 ON UPDATE 可以修复时间戳(参考 manualSET NEW.modified_by = ... 我认为可以在触发器中完成。防止篡改创建/修改的规则也可能需要在触发器中。@987654336 @实际上是正确的。另见system versioned tables
    猜你喜欢
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 2014-10-11
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    相关资源
    最近更新 更多