#### 13.7.1.6 GRANT 声明

[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)

```
GRANT
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type] priv_level
    TO user_or_role [, user_or_role] ...
    [WITH GRANT OPTION]
    [AS user
        [WITH ROLE
            DEFAULT
          | NONE
          | ALL
          | ALL EXCEPT role [, role ] ...
          | role [, role ] ...
        ]
    ]
}

GRANT PROXY ON user_or_role
    TO user_or_role [, user_or_role] ...
    [WITH GRANT OPTION]

GRANT role [, role] ...
    TO user_or_role [, user_or_role] ...
    [WITH ADMIN OPTION]

object_type: {
    TABLE
  | FUNCTION
  | PROCEDURE
}

priv_level: {
    *
  | *.*
  | db_name.*
  | db_name.tbl_name
  | tbl_name
  | db_name.routine_name
}

user_or_role: {
    user (see Section 6.2.4, “Specifying Account Names”)
  | role (see Section 6.2.5, “Specifying Role Names”)
}
```

这[`授予`](grant.html)语句将权限和角色分配给 MySQL 用户帐户和角色。有几个方面的[`授予`](grant.html)声明，在以下主题下进行描述：

-   [GRANT 概述](grant.html#grant-overview)

-   [对象引用准则](grant.html#grant-quoting)

-   [帐户名称](grant.html#grant-accounts)

-   [MySQL 支持的权限](grant.html#grant-privileges)

-   [全球特权](grant.html#grant-global-privileges)

-   [数据库权限](grant.html#grant-database-privileges)

-   [餐桌特权](grant.html#grant-table-privileges)

-   [列特权](grant.html#grant-column-privileges)

-   [存储的例程特权](grant.html#grant-routine-privileges)

-   [代理用户权限](grant.html#grant-proxy-privileges)

-   [授予角色](grant.html#grant-roles)

-   [这`作为`条款和特权限制](grant.html#grant-as)

-   [其他账户特征](grant.html#grant-other-characteristics)

-   [GRANT 的 MySQL 和标准 SQL 版本](grant.html#grant-mysql-vs-standard-sql)

##### GRANT 概述

这[`授予`](grant.html)语句使系统管理员能够授予权限和角色，这些权限和角色可以授予用户帐户和角色。这些语法限制适用：

-   [`授予`](grant.html)不能在同一语句中混合授予权限和角色。给定的[`授予`](grant.html)语句必须授予特权或角色。

-   这`在`子句区分语句是否授予特权或角色：

    -   和`在`，该语句授予特权。

    -   没有`在`，该语句授予角色。

    -   允许将权限和角色分配给一个帐户，但您必须使用单独的[`授予`](grant.html)语句，每个语句的语法都适合被授予的内容。

    有关角色的更多信息，请参阅[第 6.2.10 节，“使用角色”](roles.html).

    授予特权[`授予`](grant.html), 你必须有[`授予选项`](privileges-provided.html#priv_grant-option)权限，并且您必须拥有您授予的权限。（或者，如果您有[`更新`](privileges-provided.html#priv_update)授予表中的权限`mysql`系统模式，您可以授予任何帐户任何权限。）当[`只读`](server-system-variables.html#sysvar_read_only)系统变量已启用，[`授予`](grant.html)另外需要[`CONNECTION_ADMIN`](privileges-provided.html#priv_connection-admin)特权（或已弃用的[`极好的`](privileges-provided.html#priv_super)特权）。

[`授予`](grant.html)要么对所有命名的用户和角色成功，要么回滚，如果发生任何错误则无效。仅当对所有命名用户和角色都成功时，该语句才会写入二进制日志。

这[`撤销`](revoke.html)声明与[`授予`](grant.html)并使管理员能够删除帐户权限。看[第 13.7.1.8 节，“撤销声明”](revoke.html).

每个帐户名称都使用中描述的格式[第 6.2.4 节，“指定帐户名称”](account-names.html).每个角色名称都使用中描述的格式[第 6.2.5 节，“指定角色名称”](role-names.html).例如：

```
GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
GRANT SELECT ON world.* TO 'role3';
```

帐户或角色名称的主机名部分，如果省略，则默认为`'%'`.

通常，数据库管理员首先使用[`创建用户`](create-user.html)创建一个帐户并定义其非特权特征，例如其密码、是否使用安全连接以及对服务器资源的访问限制，然后使用[`授予`](grant.html)定义其权限。[`更改用户`](alter-user.html)可用于更改现有帐户的非特权特性。例如：

```
CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';
ALTER USER 'jeffrey'@'localhost' WITH MAX_QUERIES_PER_HOUR 90;
```

来自[**mysql**](mysql.html)程序，[`授予`](grant.html)回应`查询正常，0 行受影响`成功执行时。要确定操作会产生什么特权，请使用[`显示赠款`](show-grants.html).看[第 13.7.7.21 节，“显示授予声明”](show-grants.html).

重要的

在某些情况下，[`授予`](grant.html)可以记录在服务器日志中，也可以记录在客户端的历史文件中，例如`~/.mysql_history`，这意味着任何有权读取该信息的人都可以读取明文密码。有关服务器日志发生这种情况的条件以及如何控制它的信息，请参阅[第 6.1.2.3 节，“密码和日志记录”](password-logging.html).有关客户端日志记录的类似信息，请参阅[第 4.5.1.3 节，“mysql 客户端日志记录”](mysql-logging.html).

[`授予`](grant.html)支持最长 255 个字符的主机名（在 MySQL 8.0.17 之前为 60 个字符）。用户名最多可包含 32 个字符。数据库、表、列和例程名称最多可包含 64 个字符。

警告

*请勿尝试通过更改用户名来更改用户名的允许长度`mysql.user`系统表。这样做会导致不可预知的行为，甚至可能使用户无法登录 MySQL 服务器*.永远不要改变表的结构`mysql`系统模式以任何方式，除非通过描述的过程[第 2.11 节，“升级 MySQL”](upgrading.html).

##### 对象引用准则

[](<>)

里面的几个对象[`授予`](grant.html)语句需要引用，尽管在许多情况下引用是可选的：帐户、角色、数据库、表、列和例程名称。例如，如果一个*`用户名`*要么*`主机名`*帐户名称中的值作为不带引号的标识符是合法的，您无需引用它。但是，引号是必需的，以指定一个*`用户名`*包含特殊字符的字符串（例如`-`)，或*`主机名`*包含特殊字符或通配符的字符串，例如`%`（例如，`'测试用户'@'%.com'`）。分别引用用户名和主机名。

要指定引用值：

-   引用数据库、表、列和例程名称作为标识符。

-   引用用户名和主机名作为标识符或字符串。

-   将密码引用为字符串。

    有关字符串引用和标识符引用指南，请参阅[第 9.1.1 节，“字符串文字”](string-literals.html)， 和[第 9.2 节，“架构对象名称”](identifiers.html).

    这`_`和`%`在指定数据库名称时允许使用通配符[`授予`](grant.html)在数据库级别授予权限的语句（`授予...开启*`D b*姓名`*.*`）。这意味着，例如，使用 \`*`字符作为数据库名称的一部分，使用`\`转义字符为`\_`在里面[`授予`](grant.html)语句，以防止用户能够访问与通配符模式匹配的其他数据库（例如，`授予...开启`富\_酒吧`。* 到 ...`）。

    在权限分配中，MySQL 解释出现的未转义`_`和`%`在这些情况下，数据库名称中的 SQL 通配符作为文字字符：

-   当数据库名称不用于授予数据库级别的权限，而是用作向其他对象（例如表或例程）授予权限的限定符时（例如，`授予...开启*`数据库名称`*.*`tbl_name`*`）。

-   启用[`部分撤销`](server-system-variables.html#sysvar_partial_revokes)导致 MySQL 解释未转义`_`和`%`数据库名称中的通配符作为文字字符，就像它们被转义为`\_`和`\%`.因为这改变了 MySQL 解释权限的方式，所以建议在安装的权限分配中避免未转义的通配符[`部分撤销`](server-system-variables.html#sysvar_partial_revokes)可以启用。有关详细信息，请参阅[第 6.2.12 节，“使用部分撤销的权限限制”](partial-revokes.html).

##### 帐户名称

一种*`用户`*中的值[`授予`](grant.html)statement 表示该语句适用的 MySQL 帐户。为了适应从任意主机向用户授予权限，MySQL 支持指定*`用户`*表单中的值`'*`用户名`*'@'*`主机名`*'`.

您可以在主机名中指定通配符。例如，`'*`用户名`*'@'%.example.com'`适用于*`用户名`*对于任何主机`例子.com`域，和`'*`用户名`*'@'198.51.100.%'`适用于*`用户名`*对于任何主机`198.51.100`C 类子网。

简单的形式`'*`用户名`*'`是同义词`'*`用户名`*'@'%'`.

*MySQL 不支持用户名中的通配符*.要引用匿名用户，请指定一个具有空用户名的帐户，并使用[`授予`](grant.html)陈述：

```
GRANT ALL ON test.* TO ''@'localhost' ...;
```

在这种情况下，使用匿名用户的正确密码从本地主机连接的任何用户都被允许访问，并具有与匿名用户帐户关联的权限。

有关帐户名中的用户名和主机名值的其他信息，请参阅[第 6.2.4 节，“指定帐户名称”](account-names.html).

警告

如果您允许本地匿名用户连接到 MySQL 服务器，您还应该授予所有本地用户权限，如`'*`用户名`*'@'本地主机'`.否则，匿名用户帐户为`本地主机`在里面`mysql.user`当命名用户尝试从本地机器登录到 MySQL 服务器时使用系统表。有关详细信息，请参阅[第 6.2.6 节，“访问控制，第 1 阶段：连接验证”](connection-access.html).

要确定此问题是否适用于您，请执行以下查询，其中列出了所有匿名用户：

```
SELECT Host, User FROM mysql.user WHERE User='';
```

为避免刚刚描述的问题，请使用以下语句删除本地匿名用户帐户：

```
DROP USER ''@'localhost';
```

##### MySQL 支持的权限

下表总结了允许的静态和动态*`priv_type`*可以为[`授予`](grant.html)和[`撤销`](revoke.html)语句，以及可以授予每个特权的级别。有关每个权限的更多信息，请参阅[第 6.2.2 节，“MySQL 提供的权限”](privileges-provided.html).有关静态权限和动态权限之间差异的信息，请参阅[静态与动态特权](privileges-provided.html#static-dynamic-privileges).

[](<>)

**表 13.11 GRANT 和 REVOKE 的允许静态权限**

| 特权 | 意义和可授予级别 |
| --- | -------- |
| [`所有[特权]`](privileges-provided.html#priv_all) | 授予指定访问级别的所有权限，除了[`授予选项`](privileges-provided.html#priv_grant-option)和[`代理`](privileges-provided.html#priv_proxy). |
| [`改变`](privileges-provided.html#priv_alter) | 启用使用[`更改表`](alter-table.html).级别：全局、数据库、表。 |
| [`改变常规`](privileges-provided.html#priv_alter-routine) | 允许更改或删除存储的例程。级别：全局、数据库、常规。 |
| [`创建`](privileges-provided.html#priv_create) | 启用数据库和表创建。级别：全局、数据库、表。 |
| [`创建角色`](privileges-provided.html#priv_create-role) | 启用角色创建。级别：全球。 |
| [`创建例程`](privileges-provided.html#priv_create-routine) | 启用存储的例程创建。级别：全球，数据库。 |
| [`创建表空间`](privileges-provided.html#priv_create-tablespace) | 允许创建、更改或删除表空间和日志文件组。级别：全球。 |
| [`创建临时表`](privileges-provided.html#priv_create-temporary-tables) | 启用使用[`创建临时表`](create-table.html).级别：全球，数据库。 |
| [`创建用户`](privileges-provided.html#priv_create-user) | 启用使用[`创建用户`](create-user.html),[`删除用户`](drop-user.html),[`重命名用户`](rename-user.html)， 和[`撤销所有特权`](revoke.html).级别：全球。 |
| [`创建视图`](privileges-provided.html#priv_create-view) | 允许创建或更改视图。级别：全局、数据库、表。 |
| [`删除`](privileges-provided.html#priv_delete) | 启用使用[`删除`](delete.html).级别：全局、数据库、表。 |
| [`降低`](privileges-provided.html#priv_drop) | 启用要删除的数据库、表和视图。级别：全局、数据库、表。 |
| [`删除角色`](privileges-provided.html#priv_drop-role) | 启用要删除的角色。级别：全球。 |
| [`事件`](privileges-provided.html#priv_event) | 为 Event Scheduler 启用事件。级别：全球，数据库。 |
| [`执行`](privileges-provided.html#priv_execute) | 使用户能够执行存储的例程。级别：全局、数据库、常规。 |
| [`文件`](privileges-provided.html#priv_file) | 使用户能够使服务器读取或写入文件。级别：全球。 |
| [`授予选项`](privileges-provided.html#priv_grant-option) | 允许向其他帐户授予或删除权限。级别：全局、数据库、表、例程、代理。 |
| [`指数`](privileges-provided.html#priv_index) | 允许创建或删除索引。级别：全局、数据库、表。 |
| [`插入`](privileges-provided.html#priv_insert) | 启用使用[`插入`](insert.html).级别：全局、数据库、表、列。 |
| [`锁定表`](privileges-provided.html#priv_lock-tables) | 启用使用[`锁定表`](lock-tables.html)在您拥有[`选择`](select.html)特权。级别：全球，数据库。 |
| [`过程`](privileges-provided.html#priv_process) | 使用户能够查看所有进程[`显示进程列表`](show-processlist.html).级别：全球。 |
| [`代理`](privileges-provided.html#priv_proxy) | 启用用户代理。级别：从用户到用户。 |
| [`参考`](privileges-provided.html#priv_references) | 启用外键创建。级别：全局、数据库、表、列。 |
| [`重新加载`](privileges-provided.html#priv_reload) | 启用使用[`冲洗`](flush.html)操作。级别：全球。 |
| [`复制客户端`](privileges-provided.html#priv_replication-client) | 使用户能够询问源服务器或副本服务器在哪里。级别：全球。 |
| [`复制奴隶`](privileges-provided.html#priv_replication-slave) | 使副本能够从源读取二进制日志事件。级别：全球。 |
| [`选择`](privileges-provided.html#priv_select) | 启用使用[`选择`](select.html).级别：全局、数据库、表、列。 |
| [`显示数据库`](privileges-provided.html#priv_show-databases) | 使能够[`显示数据库`](show-databases.html)显示所有数据库。级别：全球。 |
| [`显示视图`](privileges-provided.html#priv_show-view) | 启用使用[`显示创建视图`](show-create-view.html).级别：全局、数据库、表。 |
| [`关掉`](privileges-provided.html#priv_shutdown) | 启用使用[**mysqladmin 关闭**](mysqladmin.html).级别：全球。 |
| [`极好的`](privileges-provided.html#priv_super) | 启用其他管理操作，例如[`将复制源更改为`](change-replication-source-to.html),[`将主更改为`](change-master-to.html),[`杀`](kill.html),[`清除二进制日志`](purge-binary-logs.html),[`设置全球`](set-variable.html)， 和[**mysqladmin 调试**](mysqladmin.html)命令。级别：全球。 |
| [`扳机`](privileges-provided.html#priv_trigger) | 启用触发操作。级别：全局、数据库、表。 |
| [`更新`](privileges-provided.html#priv_update) | 启用使用[`更新`](update.html).级别：全局、数据库、表、列。 |
| [`用法`](privileges-provided.html#priv_usage) | “没有特权”的同义词 |

[](<>)

**表 13.12 GRANT 和 REVOKE 允许的动态权限**

| 特权 | 意义和可授予级别 |
| --- | -------- |
| [`APPLICATION_PASSWORD_ADMIN`](privileges-provided.html#priv_application-password-admin) | 启用双重密码管理。级别：全球。 |
| [`AUDIT_ABORT_EXEMPT`](privileges-provided.html#priv_audit-abort-exempt) | 允许被审计日志过滤器阻止的查询。级别：全球。 |
| [`AUDIT_ADMIN`](privileges-provided.html#priv_audit-admin) | 启用审核日志配置。级别：全球。 |
| [`AUTHENTICATION_POLICY_ADMIN`](privileges-provided.html#priv_authentication-policy-admin) | 启用身份验证策略管理。级别：全球。 |
| [`BACKUP_ADMIN`](privileges-provided.html#priv_backup-admin) | 启用备份管理。级别：全球。 |
| [`BINLOG_ADMIN`](privileges-provided.html#priv_binlog-admin) | 启用二进制日志控制。级别：全球。 |
| [`BINLOG_ENCRYPTION_ADMIN`](privileges-provided.html#priv_binlog-encryption-admin) | 启用和停用二进制日志加密。级别：全球。 |
| [`CLONE_ADMIN`](privileges-provided.html#priv_clone-admin) | 启用克隆管理。级别：全球。 |
| [`CONNECTION_ADMIN`](privileges-provided.html#priv_connection-admin) | 启用连接限制/限制控制。级别：全球。 |
| [`ENCRYPTION_KEY_ADMIN`](privileges-provided.html#priv_encryption-key-admin) | 使能够`InnoDB`密钥轮换。级别：全球。 |
| [`FIREWALL_ADMIN`](privileges-provided.html#priv_firewall-admin) | 启用防火墙规则管理，任何用户。级别：全球。 |
| [`FIREWALL_EXEMPT`](privileges-provided.html#priv_firewall-exempt) | 免除用户的防火墙限制。级别：全球。 |
| [`FIREWALL_USER`](privileges-provided.html#priv_firewall-user) | 启用防火墙规则管理，self。级别：全球。 |
| [`FLUSH_OPTIMIZER_COSTS`](privileges-provided.html#priv_flush-optimizer-costs) | 启用优化器成本重新加载。级别：全球。 |
| [`FLUSH_STATUS`](privileges-provided.html#priv_flush-status) | 启用状态指示器刷新。级别：全球。 |
| [`FLUSH_TABLES`](privileges-provided.html#priv_flush-tables) | 启用表刷新。级别：全球。 |
| [`FLUSH_USER_RESOURCES`](privileges-provided.html#priv_flush-user-resources) | 启用用户资源刷新。级别：全球。 |
| [`GROUP_REPLICATION_ADMIN`](privileges-provided.html#priv_group-replication-admin) | 启用组复制控制。级别：全球。 |
| [`INNODB_REDO_LOG_ENABLE`](privileges-provided.html#priv_innodb-redo-log-enable) | 启用或禁用重做日志记录。级别：全球。 |
| [`INNODB_REDO_LOG_ARCHIVE`](privileges-provided.html#priv_innodb-redo-log-archive) | 启用重做日志归档管理。级别：全球。 |
| [`NDB_STORED_USER`](privileges-provided.html#priv_ndb-stored-user) | 启用 SQL 节点（NDB 集群）之间的用户或角色共享。级别：全球。 |
| [`PASSWORDLESS_USER_ADMIN`](privileges-provided.html#priv_passwordless-user-admin) | 启用无密码用户帐户管理。级别：全球。 |
| [`PERSIST_RO_VARIABLES_ADMIN`](privileges-provided.html#priv_persist-ro-variables-admin) | 启用持久化只读系统变量。级别：全球。 |
| [`REPLICATION_APPLIER`](privileges-provided.html#priv_replication-applier) | 作为`PRIVILEGE_CHECKS_USER`对于复制通道。级别：全球。 |
| [`REPLICATION_SLAVE_ADMIN`](privileges-provided.html#priv_replication-slave-admin) | 启用定期复制控制。级别：全球。 |
| [`RESOURCE_GROUP_ADMIN`](privileges-provided.html#priv_resource-group-admin) | 启用资源组管理。级别：全球。 |
| [`RESOURCE_GROUP_USER`](privileges-provided.html#priv_resource-group-user) | 启用资源组管理。级别：全球。 |
| [`ROLE_ADMIN`](privileges-provided.html#priv_role-admin) | 允许角色被授予或撤销，使用`带管理员选项`.级别：全球。 |
| [`SESSION_VARIABLES_ADMIN`](privileges-provided.html#priv_session-variables-admin) | 启用设置受限会话系统变量。级别：全球。 |
| [`SET_USER_ID`](privileges-provided.html#priv_set-user-id) | 启用设置非自我`定义者`价值观。级别：全球。 |
| [`SHOW_ROUTINE`](privileges-provided.html#priv_show-routine) | 启用对存储的例程定义的访问。级别：全球。 |
| [`SYSTEM_USER`](privileges-provided.html#priv_system-user) | 指定账户为系统账户。级别：全球。 |
| [`SYSTEM_VARIABLES_ADMIN`](privileges-provided.html#priv_system-variables-admin) | 启用修改或持久化全局系统变量。级别：全球。 |
| [`TABLE_ENCRYPTION_ADMIN`](privileges-provided.html#priv_table-encryption-admin) | 启用覆盖默认加密设置。级别：全球。 |
| [`VERSION_TOKEN_ADMIN`](privileges-provided.html#priv_version-token-admin) | 启用版本令牌功能。级别：全球。 |
| [`XA_RECOVER_ADMIN`](privileges-provided.html#priv_xa-recover-admin) | 使能够[`XA 恢复`](xa-statements.html)执行。级别：全球。 |

触发器与表相关联。要创建或删除触发器，您必须拥有[`扳机`](privileges-provided.html#priv_trigger)表的特权，而不是触发器。

在[`授予`](grant.html)声明，[`所有[特权]`](privileges-provided.html#priv_all)要么[`代理`](privileges-provided.html#priv_proxy)权限必须单独命名，不能与其他权限一起指定。[`所有[特权]`](privileges-provided.html#priv_all)代表在授予权限的级别上可用的所有权限，除了[`授予选项`](privileges-provided.html#priv_grant-option)和[`代理`](privileges-provided.html#priv_proxy)特权。

MySQL 帐户信息存储在`mysql`系统架构。更多详情，请咨询[第 6.2 节，“访问控制和帐户管理”](access-control.html)，其中讨论了`mysql`系统架构和访问控制系统广泛。

[](<>)

如果授权表包含包含混合大小写的数据库或表名的特权行，并且[`lower_case_table_names`](server-system-variables.html#sysvar_lower_case_table_names)系统变量设置为非零值，[`撤销`](revoke.html)不能用于撤销这些特权。在这种情况下，有必要直接操作授权表。([`授予`](grant.html)不创建这样的行时[`lower_case_table_names`](server-system-variables.html#sysvar_lower_case_table_names)已设置，但可能在设置该变量之前已创建此类行。这[`lower_case_table_names`](server-system-variables.html#sysvar_lower_case_table_names)设置只能在服务器启动时配置。）

可以在多个级别授予权限，具体取决于用于`在`条款。为了[`撤销`](revoke.html)， 相同`在`语法指定要删除的权限。

对于全局、数据库、表和例程级别，[`全部授予`](grant.html)仅分配在您授予的级别上存在的权限。例如，`全部授予 *`数据库名称`*.*`是数据库级语句，因此它不授予任何全局权限，例如[`文件`](privileges-provided.html#priv_file).授予[`全部`](privileges-provided.html#priv_all)不分配[`授予选项`](privileges-provided.html#priv_grant-option)要么[`代理`](privileges-provided.html#priv_proxy)特权。

这*`对象类型`*子句，如果存在，应指定为`桌子`,`功能`， 要么`程序`当以下对象是表、存储函数或存储过程时。

用户对数据库、表、列或例程所拥有的特权是作为逻辑累加形成的[`要么`](logical-operators.html#operator_or)每个权限级别的帐户权限，包括全局级别。不可能通过在较低级别缺少该特权来拒绝在较高级别授予的特权。例如，此语句授予[`选择`](privileges-provided.html#priv_select)和[`插入`](privileges-provided.html#priv_insert)全局权限：

```
GRANT SELECT, INSERT ON *.* TO u1;
```

全局授予的权限适用于所有数据库、表和列，即使未在任何较低级别授予。

从 MySQL 8.0.16 开始，可以通过为特定数据库撤销在全局级别授予的权限来显式拒绝授予的权限，如果[`部分撤销`](server-system-variables.html#sysvar_partial_revokes)系统变量已启用：

```
GRANT SELECT, INSERT, UPDATE ON *.* TO u1;
REVOKE INSERT, UPDATE ON db1.* FROM u1;
```

上述语句的结果是[`选择`](privileges-provided.html#priv_select)全局应用于所有表，而[`插入`](privileges-provided.html#priv_insert)和[`更新`](privileges-provided.html#priv_update)全局应用，除了表`db1`.帐户访问权限`db1`是只读的。

特权检查过程的详细信息在[第 6.2.7 节，“访问控制，第 2 阶段：请求验证”](request-access.html).

如果您正在为一个用户使用表、列或例程权限，服务器会检查所有用户的表、列和例程权限，这会稍微降低 MySQL 的速度。同样，如果您限制任何用户的查询、更新或连接的数量，服务器必须监控这些值。

MySQL 使您能够授予对不存在的数据库或表的权限。对于表，要授予的权限必须包括[`创建`](privileges-provided.html#priv_create)特权。*此行为是设计使然*, 并旨在使数据库管理员能够为稍后要创建的数据库或表准备用户帐户和权限。

重要的

*删除数据库或表时，MySQL 不会自动撤销任何权限*.但是，如果您删除一个例程，则为该例程授予的任何例程级别权限都将被撤销。

##### 全球特权

全局权限是管理权限或适用于给定服务器上的所有数据库。要分配全局权限，请使用`在 *。*`句法：

```
GRANT ALL ON *.* TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON *.* TO 'someuser'@'somehost';
```

这[`创建表空间`](privileges-provided.html#priv_create-tablespace),[`创建用户`](privileges-provided.html#priv_create-user),[`文件`](privileges-provided.html#priv_file),[`过程`](privileges-provided.html#priv_process),[`重新加载`](privileges-provided.html#priv_reload),[`复制客户端`](privileges-provided.html#priv_replication-client),[`复制奴隶`](privileges-provided.html#priv_replication-slave),[`显示数据库`](privileges-provided.html#priv_show-databases),[`关掉`](privileges-provided.html#priv_shutdown)， 和[`极好的`](privileges-provided.html#priv_super)静态权限是管理权限，只能全局授予。

动态权限都是全局的，只能全局授予。

其他权限可以全局授予，也可以在更具体的级别授予。

的效果[`授予选项`](privileges-provided.html#priv_grant-option)在全局级别授予的静态权限和动态权限不同：

-   [`授予选项`](privileges-provided.html#priv_grant-option)为任何静态全局权限授予的权限适用于所有静态全局权限。

-   [`授予选项`](privileges-provided.html#priv_grant-option)为任何动态权限授予的权限仅适用于该动态权限。

`全部授予`在全局级别授予所有静态全局权限和所有当前注册的动态权限。执行后注册的动态特权`授予`声明不会追溯授予任何帐户。

MySQL 将全局权限存储在`mysql.user`系统表。

##### 数据库权限

数据库权限适用于给定数据库中的所有对象。要分配数据库级权限，请使用`在 *`数据库名称`*.*`句法：

```
GRANT ALL ON mydb.* TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';
```

如果你使用`在 *`语法（而不是`在 *。*`)，权限是在默认数据库的数据库级别分配的。如果没有默认数据库，则会发生错误。

这[`创建`](privileges-provided.html#priv_create),[`降低`](privileges-provided.html#priv_drop),[`事件`](privileges-provided.html#priv_event),[`授予选项`](privileges-provided.html#priv_grant-option),[`锁定表`](privileges-provided.html#priv_lock-tables)， 和[`参考`](privileges-provided.html#priv_references)可以在数据库级别指定权限。表或例程权限也可以在数据库级别指定，在这种情况下，它们适用于数据库中的所有表或例程。

MySQL 将数据库权限存储在`mysql.db`系统表。

##### 餐桌特权

表权限适用于给定表中的所有列。要分配表级权限，请使用`在 *`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`*表级别的值是[`改变`](privileges-provided.html#priv_alter),[`创建视图`](privileges-provided.html#priv_create-view),[`创建`](privileges-provided.html#priv_create),[`删除`](privileges-provided.html#priv_delete),[`降低`](privileges-provided.html#priv_drop),[`授予选项`](privileges-provided.html#priv_grant-option),[`指数`](privileges-provided.html#priv_index),[`插入`](privileges-provided.html#priv_insert),[`参考`](privileges-provided.html#priv_references),[`选择`](privileges-provided.html#priv_select),[`显示视图`](privileges-provided.html#priv_show-view),[`扳机`](privileges-provided.html#priv_trigger)， 和[`更新`](privileges-provided.html#priv_update).

表级权限适用于基表和视图。它们不适用于使用创建的表[`创建临时表`](create-temporary-table.html)，即使表名匹配。有关信息`暂时的`表权限，请参阅[第 13.1.20.2 节，“CREATE TEMPORARY TABLE 语句”](create-temporary-table.html).

[](<>)[](<>)

MySQL 将表权限存储在`mysql.tables_priv`系统表。

##### 列特权

列权限适用于给定表中的单个列。在列级别授予的每个特权都必须跟在括号内的一个或多个列之后。

```
GRANT SELECT (col1), INSERT (col1, col2) ON mydb.mytbl TO 'someuser'@'somehost';
```

允许的*`priv_type`*列的值（即，当您使用*`列列表`*条款）是[`插入`](privileges-provided.html#priv_insert),[`参考`](privileges-provided.html#priv_references),[`选择`](privileges-provided.html#priv_select)， 和[`更新`](privileges-provided.html#priv_update).

MySQL 将列权限存储在`mysql.columns_priv`系统表。

##### 存储的例程特权

这[`改变常规`](privileges-provided.html#priv_alter-routine),[`创建例程`](privileges-provided.html#priv_create-routine),[`执行`](privileges-provided.html#priv_execute)， 和[`授予选项`](privileges-provided.html#priv_grant-option)特权适用于存储的例程（过程和函数）。可以在全局和数据库级别授予它们。除了[`创建例程`](privileges-provided.html#priv_create-routine), 这些权限可以在例程级别为各个例程授予。

```
GRANT CREATE ROUTINE ON mydb.* TO 'someuser'@'somehost';
GRANT EXECUTE ON PROCEDURE mydb.myproc TO 'someuser'@'somehost';
```

允许的*`priv_type`*常规级别的值是[`改变常规`](privileges-provided.html#priv_alter-routine),[`执行`](privileges-provided.html#priv_execute)， 和[`授予选项`](privileges-provided.html#priv_grant-option).[`创建例程`](privileges-provided.html#priv_create-routine)不是例程级别的特权，因为您必须首先具有全局或数据库级别的特权才能创建例程。

MySQL 将例程级别的权限存储在`mysql.procs_priv`系统表。

##### 代理用户权限

这[`代理`](privileges-provided.html#priv_proxy)特权使一个用户可以成为另一个用户的代理。代理用户冒充或冒用被代理用户的身份；也就是说，它假定代理用户的权限。

```
GRANT PROXY ON 'localuser'@'localhost' TO 'externaluser'@'somehost';
```

什么时候[`代理`](privileges-provided.html#priv_proxy)被授予，它必须是在[`授予`](grant.html)声明，并且唯一允许的`和`选项是`有授予选项`.

代理要求代理用户通过插件进行身份验证，该插件在代理用户连接时将代理用户的名称返回给服务器，并且代理用户具有`代理`代理用户的权限。有关详细信息和示例，请参阅[第 6.2.19 节，“代理用户”](proxy-users.html).

MySQL 将代理权限存储在`mysql.proxies_priv`系统表。

##### 授予角色

`授予`没有语法`在`子句授予角色而不是个人特权。角色是特权的命名集合；看[第 6.2.10 节，“使用角色”](roles.html).例如：

```
GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
```

要授予的每个角色以及要授予它的每个用户帐户或角色都必须存在。从 MySQL 8.0.16 开始，不能将角色授予匿名用户。

授予角色不会自动导致该角色处于活动状态。有关角色激活和停用的信息，请参阅[激活角色](roles.html#roles-activating).

授予角色需要这些权限：

-   如果你有[`ROLE_ADMIN`](privileges-provided.html#priv_role-admin)特权（或已弃用的[`极好的`](privileges-provided.html#priv_super)privilege），您可以授予或撤销用户或角色的任何角色。

-   如果您被授予一个角色[`授予`](grant.html)声明，其中包括`带管理员选项`条款，您可以将该角色授予其他用户或角色，或从其他用户或角色撤消该角色，只要该角色在您随后授予或撤消该角色时处于活动状态。这包括使用的能力`带管理员选项`本身。

-   授予具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权，您必须拥有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权。

    可以创建循环引用[`授予`](grant.html).例如：


```
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.html)有一个`作为 *`用户`* [有角色]`子句，指定有关用于语句执行的特权上下文的附加信息。这种语法在 SQL 级别是可见的，尽管它的主要目的是通过使这些限制出现在二进制日志中，在所有节点上实现由部分撤销施加的授予者权限限制的统一复制。有关部分撤销的信息，请参阅[第 6.2.12 节，“使用部分撤销的权限限制”](partial-revokes.html).

当。。。的时候`作为 *`用户`*`如果指定了子句，则语句执行会考虑与指定用户相关的任何权限限制，包括由指定的所有角色`有角色`，如果存在。结果是该语句实际授予的权限可能会相对于指定的权限减少。

这些条件适用于`作为 *`用户`*`条款：

-   `作为`仅当命名时有效*`用户`*有特权限制（这意味着[`部分撤销`](server-system-variables.html#sysvar_partial_revokes)系统变量已启用）。

-   如果`有角色`给定，所有命名的角色都必须授予命名的*`用户`*.

-   被命名的*`用户`*应该是指定为的 MySQL 帐户`'*`用户名`*'@'*`主机名`*'`,[`当前用户`](information-functions.html#function_current-user)， 要么[`当前用户（）`](information-functions.html#function_current-user).当前用户可能与`有角色`对于执行用户想要的情况[`授予`](grant.html)使用一组可能与当前会话中活动的角色不同的角色执行。

-   `作为`不能用于获得不属于执行[`授予`](grant.html)陈述。执行用户必须至少具有要授予的权限，但`作为`子句只能限制授予的权限，不能升级它们。

-   关于授予的特权，`作为`不能指定比执行[`授予`](grant.html)陈述。这`作为`允许用户/角色组合拥有比执行用户更多的权限，但前提是语句不授予这些额外权限。

-   `作为`仅支持授予全局权限（`在 *。*`）。

-   `作为`不支持[`代理`](privileges-provided.html#priv_proxy)赠款。

    下面的例子说明了效果`作为`条款。创建用户`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;
```

现在，使用自己没有权限限制的帐户，向多个用户授予相同的全局权限集，但每个用户都有不同的限制`作为`子句，并检查实际授予了哪些权限。

-   这[`授予`](grant.html)这里的声明没有`作为`子句，因此授予的权限正是指定的权限：

    ```
    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.html)这里的声明有一个`作为`子句，因此授予的特权是指定的，但具有以下限制`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`@`%`         |
    +----------------------------------------------------+
    ```

    如前所述，`作为`子句只能添加权限限制；它不能提升权限。因此，虽然`u1`有[`删除`](privileges-provided.html#priv_delete)特权，不包括在授予的特权中，因为该语句未指定授予[`删除`](privileges-provided.html#priv_delete).

-   这`作为`的条款[`授予`](grant.html)这里的声明使角色`r1`活跃于`u1`.这个角色解除了一些限制`u1`.因此，授予的特权有一些限制，但没有前面的那么多[`授予`](grant.html)陈述：

    ```
    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.html)声明包括一个`作为 *`用户`*`子句，对执行语句的用户的权限限制将被忽略（而不是像在没有`作为`条款）。

##### 其他账户特征

可选的`和`子句用于使用户能够向其他用户授予权限。这`有授予选项`子句使用户能够将其在指定特权级别上的任何特权授予其他用户。

授予[`授予选项`](privileges-provided.html#priv_grant-option)在不更改其权限的情况下授予帐户权限，请执行以下操作：

```
GRANT USAGE ON *.* TO 'someuser'@'somehost' WITH GRANT OPTION;
```

小心你给谁[`授予选项`](privileges-provided.html#priv_grant-option)权限，因为具有不同权限的两个用户可能能够组合权限！

您不能授予其他用户您自己没有的权限；这[`授予选项`](privileges-provided.html#priv_grant-option)privilege 使您能够仅分配您自己拥有的那些权限。

请注意，当您授予用户[`授予选项`](privileges-provided.html#priv_grant-option)在特定特权级别的特权，用户在该级别拥有（或将来可能授予）的任何特权也可以由该用户授予其他用户。假设您授予用户[`插入`](privileges-provided.html#priv_insert)数据库的特权。如果您随后授予[`选择`](privileges-provided.html#priv_select)对数据库的权限并指定`有授予选项`，该用户不仅可以给其他用户[`选择`](privileges-provided.html#priv_select)特权，但也[`插入`](privileges-provided.html#priv_insert).如果您随后授予[`更新`](privileges-provided.html#priv_update)授予用户对数据库的权限，用户可以授予[`插入`](privileges-provided.html#priv_insert),[`选择`](privileges-provided.html#priv_select)， 和[`更新`](privileges-provided.html#priv_update).

对于非管理员用户，您不应授予[`改变`](privileges-provided.html#priv_alter)特权全球或`mysql`系统架构。如果这样做，用户可以尝试通过重命名表来颠覆特权系统！

有关与特定权限相关的安全风险的其他信息，请参阅[第 6.2.2 节，“MySQL 提供的权限”](privileges-provided.html).

##### GRANT 的 MySQL 和标准 SQL 版本

[](<>)

MySQL与标准SQL版本的最大区别[`授予`](grant.html)是：

-   MySQL 将权限与主机名和用户名的组合相关联，而不仅仅是用户名。

-   标准 SQL 没有全局或数据库级别的权限，也不支持 MySQL 支持的所有权限类型。

-   MySQL 不支持标准 SQL`在下面`特权。

-   标准 SQL 权限以分层方式构建。如果您删除一个用户，该用户被授予的所有权限都将被撤销。如果您使用，这在 MySQL 中也是如此[`删除用户`](drop-user.html).看[第 13.7.1.5 节，“DROP USER 语句”](drop-user.html).

-   在标准 SQL 中，当您删除一个表时，该表的所有权限都会被撤销。在标准 SQL 中，当您撤销特权时，基于该特权授予的所有特权也将被撤销。在 MySQL 中，可以使用以下命令删除权限[`删除用户`](drop-user.html)要么[`撤销`](revoke.html)陈述。

-   在 MySQL 中，可以有[`插入`](privileges-provided.html#priv_insert)仅对表中的某些列具有特权。在这种情况下，您仍然可以执行[`插入`](insert.html)表上的语句，前提是您只为您拥有的那些列插入值[`插入`](privileges-provided.html#priv_insert)特权。如果未启用严格 SQL 模式，则省略的列将设置为其隐式默认值。在严格模式下，如果任何省略的列没有默认值，则该语句将被拒绝。（标准 SQL 要求您拥有[`插入`](privileges-provided.html#priv_insert)所有列的特权。）有关严​​格 SQL 模式和隐式默认值的信息，请参阅[第 5.1.11 节，“服务器 SQL 模式”](sql-mode.html)， 和[第 11.6 节，“数据类型默认值”](data-type-defaults.html).
