MySQL 账户名由用户名和主机名组成,这使得可以为来自不同主机的具有相同用户名的用户创建不同的账户。本节介绍账户名的语法,包括特殊值和通配符规则。
在大多数方面,账户名与 MySQL 角色名类似,8.2.5节,“指定角色名”中描述了一些差异。
账户名出现在 SQL 语句中,例如 CREATE USER
、GRANT
和 SET PASSWORD
,并遵循以下规则:
-
账户名语法为
'
。user_name
'@'host_name
' -
@'
部分是可选的。仅由用户名组成的账户名等同于host_name
''
。例如,user_name
'@'%''me'
等同于'me'@'%'
。 -
如果用户名和主机名作为非引用的标识符是合法的,则不需要引用它们。如果
user_name
字符串包含特殊字符(例如空格或-
),或者host_name
字符串包含特殊字符或通配符(例如.
或%
),则必须使用引号。例如,在账户名'test-user'@'%.com'
中,用户名和主机名部分都需要引号。 -
使用反引号 (
`
)、单引号 ('
) 或双引号 ("
) 将用户名和主机名引用为标识符或字符串。有关字符串引用和标识符引用指南,请参阅 11.1.1节,“字符串文字” 和 11.2节,“模式对象名”。在SHOW
语句结果中,用户名和主机名使用反引号 (`
) 引用。 -
用户名和主机名部分(如果引用)必须单独引用。也就是说,写成
'me'@'localhost'
,而不是'me@localhost'
。(后者实际上等同于'me@localhost'@'%'
,尽管此行为现在已弃用。) -
对
CURRENT_USER
或CURRENT_USER()
函数的引用等同于字面上指定当前客户端的用户名和主机名。
MySQL 使用用户名和主机名部分的单独列将账户名存储在 mysql
系统数据库的授权表中:
有关存储在授权表中的用户名和主机名属性的其他详细信息,例如最大长度,请参阅 授权表范围列属性。
用户名和主机名具有某些特殊值或通配符约定,如下所述。
帐户名的用户名部分可以是与传入连接尝试的用户名完全匹配的非空值,也可以是与任何用户名匹配的空值(空字符串)。 具有空白用户名的帐户是匿名用户。 要在 SQL 语句中指定匿名用户,请使用带引号的空用户名部分,例如 ''@'localhost'
。
帐户名的主机名部分可以采用多种形式,并且允许使用通配符:
-
主机值可以是主机名或 IP 地址(IPv4 或 IPv6)。 名称
'localhost'
表示本地主机。 IP 地址'127.0.0.1'
表示 IPv4 环回接口。 IP 地址'::1'
表示 IPv6 环回接口。 -
在主机名或 IP 地址值中允许使用
%
和_
通配符,但在 MySQL 8.2.0 及更高版本的创新版本中已弃用,并将在未来版本的 MySQL 中删除。 这些字符的含义与使用LIKE
运算符执行的模式匹配操作相同。 例如,主机值'%'
匹配任何主机名,而值'%.mysql.com'
匹配mysql.com
域中的任何主机。'198.51.100.%'
匹配 198.51.100 C 类网络中的任何主机。由于在主机值中允许使用 IP 通配符值(例如,
'198.51.100.%'
匹配子网上的每个主机),因此有人可能会尝试通过将主机命名为198.51.100.somewhere.com
来利用此功能。 为了阻止此类尝试,MySQL 不会对以数字和点开头的 主机名执行匹配。 例如,如果主机名为1.2.example.com
,则其名称永远不会匹配帐户名的主机部分。 IP 通配符值只能匹配 IP 地址,不能匹配主机名。如果
partial_revokes
设置为ON
,MySQL 会将授权中的%
和_
视为文字字符,而不是通配符。在 MySQL 8.2.0 和更高版本的创新版本中,不建议使用这些通配符(无论此变量的值如何);预计此功能将在未来版本的 MySQL 中删除。 -
对于指定为 IPv4 地址的主机值,可以提供一个网络掩码来指示用于网络号的地址位数。网络掩码表示法不能用于 IPv6 地址。
语法为
。例如:host_ip
/netmask
CREATE USER 'david'@'198.51.100.0/255.255.255.0';
这允许
david
从任何具有 IP 地址client_ip
的客户端主机连接,只要满足以下条件:client_ip & netmask = host_ip
也就是说,对于刚刚显示的
CREATE USER
语句:client_ip & 255.255.255.0 = 198.51.100.0
满足此条件的 IP 地址范围为
198.51.100.0
到198.51.100.255
。网络掩码通常以设置为 1 的位开始,后跟设置为 0 的位。例如:
-
198.0.0.0/255.0.0.0
:198 A 类网络上的任何主机 -
198.51.0.0/255.255.0.0
:198.51 B 类网络上的任何主机 -
198.51.100.0/255.255.255.0
:198.51.100 C 类网络上的任何主机 -
198.51.100.1
:仅具有此特定 IP 地址的主机
-
-
指定为 IPv4 地址的主机值可以使用 CIDR 表示法编写,例如
198.51.100.44/24
。
服务器使用系统 DNS 解析器为客户端主机名或 IP 地址返回的值,将帐户名中的主机值与客户端主机进行匹配。除非帐户主机值使用网络掩码表示法指定,否则服务器会将此比较作为字符串匹配执行,即使是作为 IP 地址提供的帐户主机值也是如此。这意味着您应该以 DNS 使用的相同格式指定帐户主机值。以下是需要注意的问题示例:
-
假设本地网络上的主机具有完全限定名称
host1.example.com
。如果 DNS 将此主机的名称查找返回为host1.example.com
,请在帐户主机值中使用该名称。如果 DNS 仅返回host1
,请改为使用host1
。 -
如果 DNS 将给定主机的 IP 地址返回为
198.51.100.2
,则它与198.51.100.2
的帐户主机值匹配,但与198.051.100.2
不匹配。类似地,它与198.51.100.%
这样的帐户主机模式匹配,但与198.051.100.%
不匹配。
为避免此类问题,建议检查 DNS 返回主机名和地址的格式。在 MySQL 帐户名中使用相同格式的值。