### 6.2.7 访问控制，第 2 阶段：请求验证

服务器接受连接后，进入访问控制的第二阶段。对于您通过连接发出的每个请求，服务器都会确定您要执行的操作，然后检查您的权限是否足够。这就是授权表中的特权列发挥作用的地方。这些特权可以来自任何`用户`,`global_grants`,`D b`,`table_priv`,`columns_priv`， 要么`procs_priv`表。（您可能会发现参考[第 6.2.3 节，“授权表”](grant-tables.html)，其中列出了每个授权表中存在的列。）

[](<>)

这`用户`和`global_grants`表授予全局权限。给定帐户的这些表中的行表示在全局基础上应用的帐户权限，无论默认数据库是什么。例如，如果`用户`表授予您[`删除`](privileges-provided.html#priv_delete)权限，您可以从服务器主机上的任何数据库中的任何表中删除行。授予权限是明智的`用户`表只提供给需要它们的人，例如数据库管理员。对于其他用户，将所有权限保留在`用户`表设置为`'N'`并仅授予更特定级别的权限（针对特定数据库、表、列或例程）。也可以全局授予数据库特权，但使用部分撤销来限制它们在特定数据库上行使（参见[第 6.2.12 节，“使用部分撤销的权限限制”](partial-revokes.html)）。

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

这`D b`table 授予特定于数据库的权限。此表的范围列中的值可以采用以下形式：

-   一个空白`用户`value 匹配匿名用户。非空值按字面意思匹配；用户名中没有通配符。

-   通配符`%`和`_`可用于`主持人`和`D b`列。这些与使用[`喜欢`](string-comparison-functions.html#operator_like)操作员。如果您想在授予权限时按字面意思使用任一字符，则必须使用反斜杠对其进行转义。例如，要包含下划线字符 (`_`) 作为数据库名称的一部分，将其指定为`\_`在里面[`授予`](grant.html)陈述。

-   一种`'%'`或空白`主持人`value 表示“任何主机”。

-   一种`'%'`或空白`D b`value 表示“任何数据库”。

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

服务器读取`D b`表到内存中，并在读取数据的同时对其进行排序`用户`桌子。服务器排序`D b`表基于`主持人`,`D b`， 和`用户`范围列。与`用户`表中，排序将最具体的值放在最前面，最不具体的值放在最后，当服务器查找匹配的行时，它使用找到的第一个匹配项。

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

这`table_priv`,`columns_priv`， 和`procs_priv`表授予特定于表、特定于列和特定于例程的权限。这些表的范围列中的值可以采用以下形式：

-   通配符`%`和`_`可用于`主持人`柱子。这些与使用[`喜欢`](string-comparison-functions.html#operator_like)操作员。

-   一种`'%'`或空白`主持人`value 表示“任何主机”。

-   这`D b`,`表名`,`列名`， 和`例程名称`列不能包含通配符或为空白。

    服务器排序`table_priv`,`columns_priv`， 和`procs_priv`基于表`主持人`,`D b`， 和`用户`列。这类似于`D b`表排序，但更简单，因为只有`主持人`列可以包含通配符。

    服务器使用排序表来验证它收到的每个请求。对于需要管理权限的请求，例如[`关掉`](privileges-provided.html#priv_shutdown)要么[`重新加载`](privileges-provided.html#priv_reload)，服务器只检查`用户`和`全局特权`表，因为这些是唯一指定管理权限的表。如果这些表中的帐户行允许请求的操作，则服务器授予访问权限，否则拒绝访问。例如，如果你想执行[**mysqladmin 关闭**](mysqladmin.html)但是你的`用户`表行不授予[`关掉`](privileges-provided.html#priv_shutdown)特权，服务器拒绝访问，甚至没有检查`D b`桌子。（后表不包含`Shutdown_priv`列，因此无需检查。）

    对于与数据库相关的请求（[`插入`](insert.html),[`更新`](update.html)，以此类推），服务器首先检查用户在`用户`表行（减去部分撤销施加的任何特权限制）。如果该行允许请求的操作，则授予访问权限。如果全局权限在`用户`表不足，服务器从`D b`桌子：

-   服务器在`D b`表上的比赛`主持人`,`D b`， 和`用户`列。

-   这`主持人`和`用户`列与连接用户的主机名和 MySQL 用户名匹配。

-   这`D b`列与用户想要访问的数据库相匹配。

-   如果没有行`主持人`和`用户`，访问被拒绝。

    在确定由数据库授予的特定于数据库的权限之后`D b`表行，服务器将它们添加到由`用户`桌子。如果结果允许所请求的操作，则授予访问权限。否则，服务器依次检查用户的表和列权限`table_priv`和`columns_priv`表，将它们添加到用户的权限，并根据结果允许或拒绝访问。对于存储例程操作，服务器使用`procs_priv`表而不是`table_priv`和`columns_priv`.

    用布尔术语表示，前面对如何计算用户权限的描述可以总结如下：


```
global privileges
OR database privileges
OR table privileges
OR column privileges
OR routine privileges
```

如果最初发现全局权限不足以执行请求的操作，那么服务器稍后会将这些权限添加到数据库、表和列权限中，这可能不是很明显。原因是一个请求可能需要不止一种权限。例如，如果您执行一个[`插入...选择`](insert-select.html)声明，你需要两个[`插入`](privileges-provided.html#priv_insert)和[`选择`](privileges-provided.html#priv_select)特权。您的特权可能是这样的`用户`表行授予一个全局权限，并且`D b`表行授予另一个专门用于相关数据库。在这种情况下，您拥有执行请求所需的权限，但服务器无法仅从您的全局权限或数据库权限中分辨出这一点。它必须根据组合的权限做出访问控制决策。
