6.2.10 Using Roles使用角色

A MySQL role is a named collection of privileges. Like user accounts, roles can have privileges granted to and revoked from them.MySQL角色是特权的命名集合。与用户帐户一样,角色可以被授予或撤销特权。

A user account can be granted roles, which grants to the account the privileges associated with each role. This enables assignment of sets of privileges to accounts and provides a convenient alternative to granting individual privileges, both for conceptualizing desired privilege assignments and implementing them.用户帐户可以被授予角色,这将授予该帐户与每个角色相关的特权。这允许向帐户分配权限集,并为授予个人权限提供了一种方便的替代方案,既可以概念化所需的权限分配,也可以实现这些权限分配。

The following list summarizes role-management capabilities provided by MySQL:以下列表总结了MySQL提供的角色管理功能:

For descriptions of individual role-manipulation statements (including the privileges required to use them), see Section 13.7.1, “Account Management Statements”. 有关单个角色操纵语句(包括使用它们所需的权限)的描述,请参阅第13.7.1节,“帐户管理语句”The following discussion provides examples of role usage. 以下讨论提供了角色使用的示例。Unless otherwise specified, SQL statements shown here should be executed using a MySQL account with sufficient administrative privileges, such as the root account.除非另有说明,否则此处显示的SQL语句应使用具有足够管理权限的MySQL帐户(如root帐户)执行。

Creating Roles and Granting Privileges to Them创建角色并授予其权限

Consider this scenario:考虑以下情况:

  • An application uses a database named app_db.应用程序使用名为app_db的数据库。

  • Associated with the application, there can be accounts for developers who create and maintain the application, and for users who interact with it.与应用程序关联,可以为创建和维护应用程序的开发人员以及与之交互的用户提供帐户。

  • Developers need full access to the database. Some users need only read access, others need read/write access.开发人员需要完全访问数据库。一些用户只需要读取权限,其他用户需要读取/写入权限。

To avoid granting privileges individually to possibly many user accounts, create roles as names for the required privilege sets. This makes it easy to grant the required privileges to user accounts, by granting the appropriate roles.为了避免单独向可能多个用户帐户授予权限,请创建角色作为所需权限集的名称。这使得通过授予适当的角色,可以轻松地向用户帐户授予所需的权限。

To create the roles, use the CREATE ROLE statement:要创建角色,请使用CREATE ROLE语句:

CREATE ROLE 'app_developer', 'app_read', 'app_write';

Role names are much like user account names and consist of a user part and host part in 'user_name'@'host_name' format. 角色名称与用户帐户名称非常相似,由'user_name'@'host_name'格式的用户部分和主机部分组成。The host part, if omitted, defaults to '%'. 如果省略主机部分,则默认为'%'The user and host parts can be unquoted unless they contain special characters such as - or %. 用户和主机部分可以取消报价,除非它们包含特殊字符,如-%Unlike account names, the user part of role names cannot be blank. 与帐户名不同,角色名的用户部分不能为空。For additional information, see Section 6.2.5, “Specifying Role Names”.有关更多信息,请参阅第6.2.5节,“指定角色名称”

To assign privileges to the roles, execute GRANT statements using the same syntax as for assigning privileges to user accounts:要为角色分配权限,请使用与为用户帐户分配权限相同的语法执行GRANT语句:

GRANT ALL ON app_db.* TO 'app_developer';
GRANT SELECT ON app_db.* TO 'app_read';
GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write';

Now suppose that initially you require one developer account, two user accounts that need read-only access, and one user account that needs read/write access. 现在假设最初您需要一个开发人员帐户、两个需要只读访问的用户帐户和一个需要读/写访问的用户帐号。Use CREATE USER to create the accounts:使用CREATE USER创建帐户:

CREATE USER 'dev1'@'localhost' IDENTIFIED BY 'dev1pass';
CREATE USER 'read_user1'@'localhost' IDENTIFIED BY 'read_user1pass';
CREATE USER 'read_user2'@'localhost' IDENTIFIED BY 'read_user2pass';
CREATE USER 'rw_user1'@'localhost' IDENTIFIED BY 'rw_user1pass';

To assign each user account its required privileges, you could use GRANT statements of the same form as just shown, but that requires enumerating individual privileges for each user. 要为每个用户帐户分配其所需的权限,您可以使用与刚才显示的形式相同的GRANT语句,但这需要枚举每个用户的单独权限。Instead, use an alternative GRANT syntax that permits granting roles rather than privileges:相反,使用允许授予角色而不是特权的替代GRANT语法:

GRANT 'app_developer' TO 'dev1'@'localhost';
GRANT 'app_read' TO 'read_user1'@'localhost', 'read_user2'@'localhost';
GRANT 'app_read', 'app_write' TO 'rw_user1'@'localhost';

The GRANT statement for the rw_user1 account grants the read and write roles, which combine to provide the required read and write privileges.rw_user1帐户的GRANT语句授予读写角色,这些角色结合在一起提供所需的读写权限。

The GRANT syntax for granting roles to an account differs from the syntax for granting privileges: There is an ON clause to assign privileges, whereas there is no ON clause to assign roles. 向帐户授予角色的GRANT语法与授予特权的语法不同:有一个ON子句来分配特权,而没有ON子句来指定角色。Because the syntaxes are distinct, you cannot mix assigning privileges and roles in the same statement. 因为语法不同,所以不能在同一语句中混合分配特权和角色。(It is permitted to assign both privileges and roles to an account, but you must use separate GRANT statements, each with syntax appropriate to what is to be granted.) (允许为帐户分配权限和角色,但必须使用单独的GRANT语句,每个语句的语法都适合要授予的内容。)As of MySQL 8.0.16, roles cannot be granted to anonymous users.从MySQL 8.0.16开始,匿名用户不能被授予角色。

A role when created is locked, has no password, and is assigned the default authentication plugin. 创建角色时,角色被锁定,没有密码,并被分配了默认的身份验证插件。(These role attributes can be changed later with the ALTER USER statement, by users who have the global CREATE USER privilege.)(具有全局CREATE USER权限的用户稍后可以使用ALTER USER语句更改这些角色属性。)

While locked, a role cannot be used to authenticate to the server. If unlocked, a role can be used to authenticate. 锁定后,角色无法用于向服务器进行身份验证。如果解锁,则可以使用角色进行身份验证。This is because roles and users are both authorization identifiers with much in common and little to distinguish them. 这是因为角色和用户都是授权标识符,它们有很多共同点,几乎没有区别。See also User and Role Interchangeability.另请参见用户和角色互换性

Defining Mandatory Roles定义强制角色

It is possible to specify roles as mandatory by naming them in the value of the mandatory_roles system variable. 通过在mandatory_roles系统变量的值中命名角色,可以将其指定为强制角色。The server treats a mandatory role as granted to all users, so that it need not be granted explicitly to any account.服务器将强制角色视为授予所有用户,因此不需要明确授予任何帐户。

To specify mandatory roles at server startup, define mandatory_roles in your server my.cnf file:要在服务器启动时指定强制角色,请在服务器my.cnf文件中定义mandatory_roles

[mysqld]
mandatory_roles='role1,role2@localhost,r3@%.example.com'

To set and persist mandatory_roles at runtime, use a statement like this:要在运行时设置和持久化mandatory_roles,请使用以下语句:

SET PERSIST mandatory_roles = 'role1,role2@localhost,r3@%.example.com';

SET PERSIST sets the value for the running MySQL instance. It also saves the value, causing it to carry over to subsequent server restarts. SET PERSIST设置正在运行的MySQL实例的值。它还保存了该值,使其延续到后续的服务器重启。To change the value for the running MySQL instance without having it carry over to subsequent restarts, use the GLOBAL keyword rather than PERSIST. 要更改正在运行的MySQL实例的值而不将其转移到后续重启,请使用GLOBAL关键字而不是PERSISTSee Section 13.7.6.1, “SET Syntax for Variable Assignment”.请参阅第13.7.6.1节,“变量赋值的SET语法”

Setting mandatory_roles requires the ROLE_ADMIN privilege, in addition to the SYSTEM_VARIABLES_ADMIN privilege (or the deprecated SUPER privilege) normally required to set a global system variable.除了设置全局系统变量通常需要的SYSTEM_VARIABLES_ADMIN权限(或已弃用的SUPER权限)外,设置mandatory_roles还需要ROLE_ADMIN权限。

Mandatory roles, like explicitly granted roles, do not take effect until activated (see Activating Roles). 强制角色,如明确授予的角色,在激活之前不会生效(请参阅激活角色)。At login time, role activation occurs for all granted roles if the activate_all_roles_on_login system variable is enabled, or for roles that are set as default roles otherwise. 在登录时,如果启用了activate_all_roles_on_login系统变量,则所有授予的角色都会激活角色,否则设置为默认角色的角色也会激活角色。At runtime, SET ROLE activates roles.在运行时,SET ROLE会激活角色。

Roles named in the value of mandatory_roles cannot be revoked with REVOKE or dropped with DROP ROLE or DROP USER.mandatory_roles的值中命名的角色不能使用REVOKE撤销,也不能使用DROP ROLEDROP USER删除。

To prevent sessions from being made system sessions by default, a role that has the SYSTEM_USER privilege cannot be listed in the value of the mandatory_roles system variable:为了防止会话在默认情况下成为系统会话,具有SYSTEM_USER权限的角色不能列在mandatory_roles系统变量的值中:

  • If mandatory_roles is assigned a role at startup that has the SYSTEM_USER privilege, the server writes a message to the error log and exits.如果在启动时为mandatory_roles分配了具有SYSTEM_USER权限的角色,则服务器会将消息写入错误日志并退出。

  • If mandatory_roles is assigned a role at runtime that has the SYSTEM_USER privilege, an error occurs and the mandatory_roles value remains unchanged.如果在运行时为mandatory_roles分配了具有SYSTEM_USER权限的角色,则会发生错误,mandatory_roles值保持不变。

If a role named in mandatory_roles is not present in the mysql.user system table, the role is not granted to users. 如果mysql.user系统表中不存在名为mandatory_roles的角色,则不会将该角色授予用户。When the server attempts role activation for a user, it does not treat the nonexistent role as mandatory and writes a warning to the error log. 当服务器尝试为用户激活角色时,它不会将不存在的角色视为强制角色,并将警告写入错误日志。If the role is created later and thus becomes valid, FLUSH PRIVILEGES may be necessary to cause the server to treat it as mandatory.如果稍后创建角色并因此生效,则可能需要FLUSH PRIVILEGES(刷新权限),以使服务器将其视为强制性的。

SHOW GRANTS displays mandatory roles according to the rules described in Section 13.7.7.21, “SHOW GRANTS Statement”.SHOW GRANTS根据第13.7.7.21节,“SHOW GRANTS语句”中所述的规则显示强制性角色。

Checking Role Privileges检查角色权限

To verify the privileges assigned to an account, use SHOW GRANTS. For example:要验证分配给帐户的权限,请使用SHOW GRANTS。例如:

mysql> SHOW GRANTS FOR 'dev1'@'localhost';
+-------------------------------------------------+
| Grants for dev1@localhost                       |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO `dev1`@`localhost`        |
| GRANT `app_developer`@`%` TO `dev1`@`localhost` |
+-------------------------------------------------+

However, that shows each granted role without expanding it to the privileges the role represents. To show role privileges as well, add a USING clause naming the granted roles for which to display privileges:然而,这显示了每个授予的角色,而没有将其“扩展”到角色所代表的特权。要同时显示角色权限,请添加一个USING子句,命名要显示权限的已授予角色:

mysql> SHOW GRANTS FOR 'dev1'@'localhost' USING 'app_developer';
+----------------------------------------------------------+
| Grants for dev1@localhost                                |
+----------------------------------------------------------+
| GRANT USAGE ON *.* TO `dev1`@`localhost`                 |
| GRANT ALL PRIVILEGES ON `app_db`.* TO `dev1`@`localhost` |
| GRANT `app_developer`@`%` TO `dev1`@`localhost`          |
+----------------------------------------------------------+

Verify each other type of user similarly:以类似的方式验证其他类型的用户:

mysql> SHOW GRANTS FOR 'read_user1'@'localhost' USING 'app_read';
+--------------------------------------------------------+
| Grants for read_user1@localhost                        |
+--------------------------------------------------------+
| GRANT USAGE ON *.* TO `read_user1`@`localhost`         |
| GRANT SELECT ON `app_db`.* TO `read_user1`@`localhost` |
| GRANT `app_read`@`%` TO `read_user1`@`localhost`       |
+--------------------------------------------------------+
mysql> SHOW GRANTS FOR 'rw_user1'@'localhost' USING 'app_read', 'app_write';
+------------------------------------------------------------------------------+
| Grants for rw_user1@localhost                                                |
+------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `rw_user1`@`localhost`                                 |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `app_db`.* TO `rw_user1`@`localhost` |
| GRANT `app_read`@`%`,`app_write`@`%` TO `rw_user1`@`localhost`               |
+------------------------------------------------------------------------------+

SHOW GRANTS displays mandatory roles according to the rules described in Section 13.7.7.21, “SHOW GRANTS Statement”.SHOW GRANTS根据第13.7.7.21节,“SHOW GRANTS语句”中所述的规则显示强制性角色。

Activating Roles激活角色

Roles granted to a user account can be active or inactive within account sessions. If a granted role is active within a session, its privileges apply; otherwise, they do not. 授予用户帐户的角色在帐户会话中可以是活动的或非活动的。如果授予的角色在会话中处于活动状态,则其特权适用;否则,他们不会。To determine which roles are active within the current session, use the CURRENT_ROLE() function.要确定当前会话中哪些角色处于活动状态,请使用current_ROLE()函数。

By default, granting a role to an account or naming it in the mandatory_roles system variable value does not automatically cause the role to become active within account sessions. 默认情况下,向帐户授予角色或在mandatory_roles系统变量值中命名角色不会自动导致该角色在帐户会话中处于活动状态。For example, because thus far in the preceding discussion no rw_user1 roles have been activated, if you connect to the server as rw_user1 and invoke the CURRENT_ROLE() function, the result is NONE (no active roles):例如,由于在前面的讨论中到目前为止还没有激活rw_user1角色,如果您以rw_user2身份连接到服务器并调用CURRENT_ROLE()函数,结果为NONE(没有活动角色):

mysql> SELECT CURRENT_ROLE();
+----------------+
| CURRENT_ROLE() |
+----------------+
| NONE           |
+----------------+

To specify which roles should become active each time a user connects to the server and authenticates, use SET DEFAULT ROLE. To set the default to all assigned roles for each account created earlier, use this statement:要指定每次用户连接到服务器并进行身份验证时应激活哪些角色,请使用SET DEFAULT ROLE。要为之前创建的每个帐户的所有分配角色设置默认值,请使用以下语句:

SET DEFAULT ROLE ALL TO
  'dev1'@'localhost',
  'read_user1'@'localhost',
  'read_user2'@'localhost',
  'rw_user1'@'localhost';

Now if you connect as rw_user1, the initial value of CURRENT_ROLE() reflects the new default role assignments:现在,如果您以rw_user1连接,CURRENT_ROLE()的初始值将反映新的默认角色分配:

mysql> SELECT CURRENT_ROLE();
+--------------------------------+
| CURRENT_ROLE()                 |
+--------------------------------+
| `app_read`@`%`,`app_write`@`%` |
+--------------------------------+

To cause all explicitly granted and mandatory roles to be automatically activated when users connect to the server, enable the activate_all_roles_on_login system variable. By default, automatic role activation is disabled.要在用户连接到服务器时自动激活所有明确授予和强制的角色,请启用activate_all_roles_on_login系统变量。默认情况下,禁用自动角色激活。

Within a session, a user can execute SET ROLE to change the set of active roles. For example, for rw_user1:在会话中,用户可以执行SET ROLE来更改活动角色集。例如,对于rw_user1

mysql> SET ROLE NONE; SELECT CURRENT_ROLE();
+----------------+
| CURRENT_ROLE() |
+----------------+
| NONE           |
+----------------+
mysql> SET ROLE ALL EXCEPT 'app_write'; SELECT CURRENT_ROLE();
+----------------+
| CURRENT_ROLE() |
+----------------+
| `app_read`@`%` |
+----------------+
mysql> SET ROLE DEFAULT; SELECT CURRENT_ROLE();
+--------------------------------+
| CURRENT_ROLE()                 |
+--------------------------------+
| `app_read`@`%`,`app_write`@`%` |
+--------------------------------+

The first SET ROLE statement deactivates all roles. The second makes rw_user1 effectively read only. The third restores the default roles.第一个SET ROLE语句停用所有角色。第二个使rw_user1有效地成为只读。第三个恢复默认角色。

The effective user for stored program and view objects is subject to the DEFINER and SQL SECURITY attributes, which determine whether execution occurs in invoker or definer context (see Section 25.6, “Stored Object Access Control”):存储程序和视图对象的有效用户受DEFINERSQL SECURITY属性的约束,这些属性决定了执行是在调用者还是定义者上下文中发生(参阅第25.6节,“存储对象访问控制”):

  • Stored program and view objects that execute in invoker context execute with the roles that are active within the current session.在调用程序上下文中执行的存储程序和视图对象与当前会话中活动的角色一起执行。

  • Stored program and view objects that execute in definer context execute with the default roles of the user named in their DEFINER attribute. 在定义者上下文中执行的存储程序和视图对象使用其DEFINER属性中指定的用户的默认角色执行。If activate_all_roles_on_login is enabled, such objects execute with all roles granted to the DEFINER user, including mandatory roles. 如果启用了activate_all_roles_on_login,则此类对象将使用授予DEFINER用户的所有角色(包括强制角色)执行。For stored programs, if execution should occur with roles different from the default, the program body should execute SET ROLE to activate the required roles.对于存储的程序,如果执行时角色与默认角色不同,程序体应执行SET ROLE以激活所需的角色。

Revoking Roles or Role Privileges撤销角色或角色权限

Just as roles can be granted to an account, they can be revoked from an account:正如可以向帐户授予角色一样,也可以从帐户中撤销角色:

REVOKE role FROM user;

Roles named in the mandatory_roles system variable value cannot be revoked.无法撤销mandatory_roles系统变量值中指定的角色。

REVOKE can also be applied to a role to modify the privileges granted to it. This affects not only the role itself, but any account granted that role. REVOKE还可以应用于角色以修改授予它的权限。这不仅会影响角色本身,还会影响授予该角色的任何帐户。Suppose that you want to temporarily make all application users read only. 假设您想暂时将所有应用程序用户设置为只读。To do this, use REVOKE to revoke the modification privileges from the app_write role:为此,使用REVOKE撤销app_write角色的修改权限:

REVOKE INSERT, UPDATE, DELETE ON app_db.* FROM 'app_write';

As it happens, that leaves the role with no privileges at all, as can be seen using SHOW GRANTS (which demonstrates that this statement can be used with roles, not just users):碰巧的是,这使得角色根本没有特权,正如使用SHOW GRANTS可以看到的那样(这表明此语句可以用于角色,而不仅仅是用户):

mysql> SHOW GRANTS FOR 'app_write';
+---------------------------------------+
| Grants for app_write@%                |
+---------------------------------------+
| GRANT USAGE ON *.* TO `app_write`@`%` |
+---------------------------------------+

Because revoking privileges from a role affects the privileges for any user who is assigned the modified role, rw_user1 now has no table modification privileges (INSERT, UPDATE, and DELETE are no longer present):因为撤销角色的权限会影响被分配了修改后角色的任何用户的权限,所以rw_user1现在没有表修改权限(INSERTUPDATEDELETE不再存在):

mysql> SHOW GRANTS FOR 'rw_user1'@'localhost'
USING 'app_read', 'app_write';
+----------------------------------------------------------------+
| Grants for rw_user1@localhost                                  |
+----------------------------------------------------------------+
| GRANT USAGE ON *.* TO `rw_user1`@`localhost`                   |
| GRANT SELECT ON `app_db`.* TO `rw_user1`@`localhost`           |
| GRANT `app_read`@`%`,`app_write`@`%` TO `rw_user1`@`localhost` |
+----------------------------------------------------------------+

In effect, the rw_user1 read/write user has become a read-only user. This also occurs for any other accounts that are granted the app_write role, illustrating how use of roles makes it unnecessary to modify privileges for individual accounts.实际上,rw_user1读/写用户已成为只读用户。这也适用于被授予app_write角色的任何其他帐户,说明了使用角色如何使不必修改单个帐户的权限。

To restore modification privileges to the role, simply re-grant them:要恢复角色的修改权限,只需重新授予它们:

GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write';

Now rw_user1 again has modification privileges, as do any other accounts granted the app_write role.现在rw_user1再次具有修改权限,授予app_write角色的任何其他帐户也是如此。

Dropping Roles删除角色

To drop roles, use DROP ROLE:要删除角色,请使用DROP ROLE

DROP ROLE 'app_read', 'app_write';

Dropping a role revokes it from every account to which it was granted.删除角色会将其从授予它的每个帐户中撤销。

Roles named in the mandatory_roles system variable value cannot be dropped.不能删除mandatory_Roles系统变量值中指定的角色。

User and Role Interchangeability用户和角色互换性

As has been hinted at earlier for SHOW GRANTS, which displays grants for user accounts or roles, accounts and roles can be used interchangeably.正如前面提到的SHOW GRANTS,它显示用户帐户或角色的授权,帐户和角色可以互换使用。

One difference between roles and users is that CREATE ROLE creates an authorization identifier that is locked by default, whereas CREATE USER creates an authorization identifier that is unlocked by default. 角色和用户之间的一个区别是,CREATE ROLE创建了一个默认锁定的授权标识符,而CREATE USER创建的是一个默认解锁的授权标识符。However, distinction is not immutable because a user with appropriate privileges can lock or unlock roles or users after they have been created.然而,这种区别并非一成不变,因为具有适当权限的用户可以在创建角色或用户后锁定或解锁它们。

If a database administrator has a preference that a specific authorization identifier must be a role, a name scheme can be used to communicate this intention. 如果数据库管理员希望特定的授权标识符必须是角色,则可以使用名称方案来传达这一意图。For example, you could use a r_ prefix for all authorization identifiers that you intend to be roles and nothing else.例如,您可以为所有您打算成为角色的授权标识符使用r_前缀,而不使用其他前缀。

Another difference between roles and users lies in the privileges available for administering them:角色和用户之间的另一个区别在于管理它们的权限:

Thus, the CREATE ROLE and DROP ROLE privileges are not as powerful as CREATE USER and may be granted to users who should only be permitted to create and drop roles, and not perform more general account manipulation.因此,CREATE ROLEDROP ROLE权限不如CREATE USER强大,可能授予只应被允许创建和删除角色的用户,而不应执行更一般的帐户操作。

With regard to privileges and interchangeability of users and roles, you can treat a user account like a role and grant that account to another user or a role. The effect is to grant the account's privileges and roles to the other user or role.关于用户和角色的特权和互换性,您可以将用户帐户视为角色,并将该帐户授予另一个用户或角色。其效果是将帐户的权限和角色授予其他用户或角色。

This set of statements demonstrates that you can grant a user to a user, a role to a user, a user to a role, or a role to a role:这组语句演示了您可以将用户授予用户、角色授予用户、用户授予角色或角色授予角色:

CREATE USER 'u1';
CREATE ROLE 'r1';
GRANT SELECT ON db1.* TO 'u1';
GRANT SELECT ON db2.* TO 'r1';
CREATE USER 'u2';
CREATE ROLE 'r2';
GRANT 'u1', 'r1' TO 'u2';
GRANT 'u1', 'r1' TO 'r2';

The result in each case is to grant to the grantee object the privileges associated with the granted object. After executing those statements, each of u2 and r2 have been granted privileges from a user (u1) and a role (r1):在每种情况下,结果都是向被授予对象授予与被授予对象相关的特权。执行这些语句后,u2r2中的每一个都被用户(u1)和角色(r1)授予了特权:

mysql> SHOW GRANTS FOR 'u2' USING 'u1', 'r1';
+-------------------------------------+
| Grants for u2@%                     |
+-------------------------------------+
| GRANT USAGE ON *.* TO `u2`@`%`      |
| GRANT SELECT ON `db1`.* TO `u2`@`%` |
| GRANT SELECT ON `db2`.* TO `u2`@`%` |
| GRANT `u1`@`%`,`r1`@`%` TO `u2`@`%` |
+-------------------------------------+
mysql> SHOW GRANTS FOR 'r2' USING 'u1', 'r1';
+-------------------------------------+
| Grants for r2@%                     |
+-------------------------------------+
| GRANT USAGE ON *.* TO `r2`@`%`      |
| GRANT SELECT ON `db1`.* TO `r2`@`%` |
| GRANT SELECT ON `db2`.* TO `r2`@`%` |
| GRANT `u1`@`%`,`r1`@`%` TO `r2`@`%` |
+-------------------------------------+

The preceding example is illustrative only, but interchangeability of user accounts and roles has practical application, such as in the following situation: Suppose that a legacy application development project began before the advent of roles in MySQL, so all user accounts associated with the project are granted privileges directly (rather than granted privileges by virtue of being granted roles). 前面的例子只是说明性的,但用户帐户和角色的可互换性具有实际应用,例如在以下情况下:假设一个遗留应用程序开发项目在MySQL中角色出现之前就开始了,因此与该项目相关的所有用户帐户都被直接授予特权(而不是通过授予角色来授予特权)。One of these accounts is a developer account that was originally granted privileges as follows:其中一个帐户是最初被授予以下特权的开发人员帐户:

CREATE USER 'old_app_dev'@'localhost' IDENTIFIED BY 'old_app_devpass';
GRANT ALL ON old_app.* TO 'old_app_dev'@'localhost';

If this developer leaves the project, it becomes necessary to assign the privileges to another user, or perhaps multiple users if development activies have expanded. Here are some ways to deal with the issue:如果此开发人员离开项目,则有必要将权限分配给另一个用户,或者如果开发活动已经扩展,则可能分配给多个用户。以下是处理这个问题的一些方法:

  • Without using roles: Change the account password so the original developer cannot use it, and have a new developer use the account instead:不使用角色:更改帐户密码,使原始开发人员无法使用它,并让新开发人员使用该帐户:

    ALTER USER 'old_app_dev'@'localhost' IDENTIFIED BY 'new_password';
  • Using roles: Lock the account to prevent anyone from using it to connect to the server:使用角色:锁定帐户以防止任何人使用它连接到服务器:

    ALTER USER 'old_app_dev'@'localhost' ACCOUNT LOCK;

    Then treat the account as a role. For each developer new to the project, create a new account and grant to it the original developer account:然后将该帐户视为一个角色。对于每个新加入项目的开发人员,创建一个新帐户并授予其原始开发人员帐户:

    CREATE USER 'new_app_dev1'@'localhost' IDENTIFIED BY 'new_password';
    GRANT 'old_app_dev'@'localhost' TO 'new_app_dev1'@'localhost';

    The effect is to assign the original developer account privileges to the new account.其效果是将原始开发人员帐户权限分配给新帐户。