全局权限是对给定服务器上的所有数据库进行的管理或应用。要分配全局权限,请使用 ON *.* 语法:GRANT ALL ON *.* TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON *.* TO 'someuser'@'somehost';
CREATE TABLESPACE、CREATE USER、FILE、PROCESS、RELOAD、REPLICATION CLIENT、REPLICATION SLAVE、SHOW DATABASES、SHUTDOWN 和 SUPER 静态权限是管理权限,只能全局授予。在全局级别授予的 GRANT OPTION 对静态和动态权限的影响不同:● 为任何静态全局权限授予的 GRANT OPTION 应用于所有静态全局权限。● 为任何动态权限授予的 GRANT OPTION 仅应用于该动态权限。GRANT ALL 在全局级别授予所有静态全局权限和所有当前注册的动态权限。在执行 GRANT 语句之后注册的动态权限不会追溯到任何帐户。MySQL 将全局权限存储在 mysql.user 系统表。数据库权限应用于给定数据库中的所有对象。要分配数据库级权限,请使用 ON db_name.* 语法:GRANT ALL ON mydb.* TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';
如果使用 ON * 语法(而不是 ON *.*),则会在数据库级别为默认数据库分配权限。如果没有默认数据库,则会发生错误。可以在数据库级别指定 CREATE、DROP、EVENT、GRANT OPTION、LOCK TABLES 和 REFERENCES 权限。表或例程权限也可以在数据库级别指定,在这种情况下,它们应用于数据库中的所有表或例程。MySQL 将数据库权限存储在 mysql.db 系统表。表权限应用于给定表中的所有列。要分配表级权限,请使用 ON db_name.tbl_name 语法:GRANT ALL ON mydb.mytbl TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON mydb.mytbl TO 'someuser'@'somehost';
如果指定 tbl_name 而不是 db_name.tbl_name,则该语句应用于默认数据库中的 tbl_name。如果没有默认数据库,则会发生错误。表级别上允许的 priv_type 值有 ALTER、CREATE VIEW、CREATE、DELETE、DROP、GRANT OPTION、INDEX、INSERT、REFERENCES、SELECT、SHOW VIEW、TRIGGER 和 UPDATE。表级权限应用于基本表和视图。即使表名匹配,它们也不适用于使用 CREATE TEMPORARY TABLE 创建的表。MySQL 将表权限存储在 mysql.tables_priv 系统表。列权限应用于给定表中的单个列。在列级别授予的每个权限后面必须跟有一个或多个列,并用括号括起来。GRANT SELECT (col1), INSERT (col1, col2) ON mydb.mytbl TO 'someuser'@'somehost';
列的允许 priv_type 值(即,在使用 column_list 子句时)是 INSERT、REFERENCES、SELECT 和 UPDATE。MySQL 将列权限存储在 mysql.columns_priv 系统表。ALTER ROUTINE、CREATE ROUTINE、EXECUTE 和 GRANT OPTION 权限应用于存储例程(过程和函数)。可以在全局和数据库级别授予它们。除了 CREATE ROUTINE 之外,这些权限可以在例程级别为单个例程授予。GRANT CREATE ROUTINE ON mydb.* TO 'someuser'@'somehost';
GRANT EXECUTE ON PROCEDURE mydb.myproc TO 'someuser'@'somehost';
例程级别允许的 priv_type 值有 ALTER ROUTINE、EXECUTE 和 GRANT OPTION。CREATE ROUTINE 不是例程级别的权限,因为您首先必须具有全局或数据库级别的权限才能创建例程。MySQL 将例程级别权限存储在 mysql.procs_priv 系统表。PROXY 权限允许一个用户成为另一个用户的代理。代理用户模拟或获取被代理用户的身份;也就是说,它取得被代理用户的权限。GRANT PROXY ON 'localuser'@'localhost' TO 'externaluser'@'somehost';
授予 PROXY 权限时,它必须是 GRANT 语句中指定的唯一权限,并且唯一允许的 WITH 选项是 WITH GRANT OPTION。代理要求代理用户通过插件进行身份验证,该插件在代理用户连接时向服务器返回被代理用户的名称,并且代理用户具有被代理用户的 PROXY 权限。MySQL 将代理权限存储在 mysql.proxies_priv 系统表。没有 ON 子句的 GRANT 语法授予角色而不是单个权限。角色是命名的权限集合。例如:GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
要授予的每个角色,以及要授予该角色的每个用户帐户和角色都必须存在。从 MySQL 8.0.16 开始,不能将角色授予匿名用户。● 如果您拥有 ROLE_ADMIN 权限(或不推荐使用的 SUPER 权限),则可以向用户或角色授予或撤销任何角色。● 如果通过使用带有 WITH ADMIN OPTION 子句的 GRANT 语句为您被授予了角色,则您可以将该角色授予其他用户或角色,或从其他用户或角色撤销该角色,只要该角色在您随后授予或撤销该角色时处于活动状态。包括使用 WITH ADMIN OPTION 的能力。● 要授予具有 SYSTEM_USER 权限的角色,必须具有 SYSTEM_USER 权限。CREATE USER 'u1', 'u2';
CREATE ROLE 'r1', 'r2';
GRANT 'u1' TO 'u1'; -- simple loop: u1 => u1
GRANT 'r1' TO 'r1'; -- simple loop: r1 => r1
GRANT 'r2' TO 'u2';
GRANT 'u2' TO 'r2'; -- mixed user/role loop: u2 => r2 => u2
允许循环授予引用,但不向被授予者添加新的权限或角色,因为用户或角色已具有其权限和角色。从 MySQL 8.0.16 开始,GRANT 有一个 As user [WITH ROLE] 子句,它指定了有关用于语句执行的权限上下文的附加信息。这种语法在 SQL 级别是可见的,尽管它的主要目的是通过在二进制日志中显示部分撤销所施加的授予者权限限制,使这些限制能够跨所有节点进行统一复制。当指定 AS user 子句时,语句执行会考虑与指定用户相关联的任何权限限制,包括 WITH ROLE 指定的所有角色(如果存在)。结果是语句实际授予的权限可能会相对于指定的权限减少。● AS 只有在指定 user 有权限限制时才有效(这意味着启用了 partial_revokes 系统变量)。● 如果给定 WITH ROLE,则必须将所有指定的角色授予指定 user。● 指定的 user 应该是指定为 'user_name'@'host_name'、CURRENT_USER 或 CURRENT_USER() 的 MySQL 帐户。当前用户可以与 WITH ROLE 一起指定,以便执行用户希望 GRANT 使用一组应用的角色执行,这些角色可能与当前会话中的活动角色不同。● AS 不能用于获得执行 GRANT 语句的用户不拥有的权限。执行用户必须至少拥有要授予的权限,但是 AS 子句只能限制授予的权限,而不能将其升级。● 对于要授予的权限,AS 不能指定一个比执行 GRANT 语句的用户拥有更多权限(更少限制)的用户/角色组合。AS 用户/角色组合被允许拥有比执行用户更多的权限,但只是在语句没有授予这些额外权限的情况下。下面的例子说明了 AS 子句的作用。创建一个用户 u1,该用户具有一些全局权限,以及对这些权限的限制:CREATE USER u1;
GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
REVOKE INSERT, UPDATE ON schema1.* FROM u1;
REVOKE SELECT ON schema2.* FROM u1;
同时创建一个角色 r1,取消一些权限限制,并将该角色授予 u1:CREATE ROLE r1;
GRANT INSERT ON schema1.* TO r1;
GRANT SELECT ON schema2.* TO r1;
GRANT r1 TO u1;
现在,使用一个没有权限限制的帐户,向多个用户授予相同的全局权限,但每个权限都有 AS 子句施加的不同限制,并检查实际上授予了哪些权限。● 这里的 GRANT 语句没有 AS 子句,所以被授予的权限就是指定的那些:mysql> CREATE USER u2;
mysql> GRANT SELECT, INSERT, UPDATE ON *.* TO u2;
mysql> SHOW GRANTS FOR u2;
+-------------------------------------------------+
| Grants for u2@% |
+-------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE ON *.* TO `u2`@`%` |
+-------------------------------------------------+
● 这里的 GRANT 语句有一个 AS 子句,所以被授予的权限是那些指定的但受到 u1 限制的权限:mysql> CREATE USER u3;
mysql> GRANT SELECT, INSERT, UPDATE ON *.* TO u3 AS u1;
mysql> SHOW GRANTS FOR u3;
+----------------------------------------------------+
| Grants for u3@% |
+----------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE ON *.* TO `u3`@`%` |
| REVOKE INSERT, UPDATE ON `schema1`.* FROM `u3`@`%` |
| REVOKE SELECT ON `schema2`.* FROM `u3`@`%` |
+----------------------------------------------------+
如前所述,AS 子句只能添加权限限制;它不能升级权限。因此,虽然 u1 拥有 DELETE 权限,但由于语句没有指定授予 DELETE 权限,所以它不包含在被授予的权限中。● 这里 GRANT 语句的 AS 子句使角色 r1 成为 u1 的活动角色。这个角色解除了对 u1 的一些限制。因此,被授予的权限有一些限制,但没有以前的 GRANT 语句那么多:mysql> CREATE USER u4;
mysql> GRANT SELECT, INSERT, UPDATE ON *.* TO u4 AS u1 WITH ROLE r1;
mysql> SHOW GRANTS FOR u4;
+-------------------------------------------------+
| Grants for u4@% |
+-------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE ON *.* TO `u4`@`%` |
| REVOKE UPDATE ON `schema1`.* FROM `u4`@`%` |
+-------------------------------------------------+
如果 GRANT 语句包含 AS user 子句,执行该语句的用户的权限限制将被忽略(而不是像没有 AS 子句时那样应用)。可选的 WITH 子句用于允许用户将权限授予其他用户。WITH GRANT OPTION 子句允许用户将其在指定权限级别上拥有的任何权限授予其他用户。要将 GRANT OPTION 权限授予账户而不更改其权限,可以这样做:GRANT USAGE ON *.* TO 'someuser'@'somehost' WITH GRANT OPTION;
要注意授予 GRANT OPTION 权限的用户,因为具有不同权限的两个用户可能会组合权限!不能将自己没有的权限授予其他用户,GRANT OPTION 权限使您只分配自己拥有的权限。请注意,当您以特定的权限级别授予用户 GRANT OPTION 权限时,该用户在该级别拥有的(或将来可能授予的)任何权限也可以由该用户授予其他用户。假设您授予用户数据库上的 INSERT 权限,然后在数据库上授予 SELECT 权限,并指定 WITH GRANT OPTION,那么该用户不仅可以授予其他用户 SELECT 权限,还可以授予 INSERT 权限。如果再将数据库上的 UPDATE 权限授予用户,则该用户可以授予 INSERT、SELECT 和 UPDATE 权限。对于非管理用户,不应该全局授予 ALTER 权限,或对 mysql 系统模式授予 ALTER 权限。如果这样做,用户可以尝试通过重命名表来破坏权限系统!MySQL 和标准 SQL 版本 GRANT 的最大区别是:● MySQL 将权限与主机名和用户名相关联,而不仅仅是用户名。● 标准 SQL 没有全局或数据库级权限,也不支持 MySQL 支持的所有权限类型。● MySQL 不支持标准的 SQL UNDER 权限。● 标准 SQL 权限是以层次结构的方式构建的。如果删除用户,则该用户已授予的所有权限都将被撤销。如果你使用 DROP USER 命令,这在 MySQL 中也适用。● 在标准 SQL 中,当删除一个表时,该表的所有权限都会被撤销。在标准 SQL 中,当撤销一个权限时,基于该权限授予的所有权限也会被撤销。在 MySQL 中,可以使用 DROP USER 或 REVOKE 语句来删除权限。● 在 MySQL 中,可能只对表中的一些列具有 INSERT 权限。在这种情况下,您仍然可以在表上执行 INSERT 语句,前提是仅为拥有 INSERT 权限的列插入值。如果没有启用严格 SQL 模式,省略的列将被设置为隐式默认值。在严格模式下,如果省略的任何列没有默认值,则该语句将被拒绝。(标准 SQL 要求您对所有列拥有 INSERT 权限。)https://dev.mysql.com/doc/refman/8.0/en/grant.html