用户
语法
CREATE USER [IF NOT EXISTS]
user [auth_option] [, user [auth_option]] ...
[REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
[WITH resource_option [resource_option] ...]
[password_option | lock_option] ...
user:
(see Section 6.2.4, “Specifying Account Names”)
auth_option: {
IDENTIFIED BY 'auth_string'
| IDENTIFIED WITH auth_plugin
| IDENTIFIED WITH auth_plugin BY 'auth_string'
| IDENTIFIED WITH auth_plugin AS 'auth_string'
| IDENTIFIED BY PASSWORD 'auth_string'
}
tls_option: {
SSL
| X509
| CIPHER 'cipher'
| ISSUER 'issuer'
| SUBJECT 'subject'
}
resource_option: {
MAX_QUERIES_PER_HOUR count
| MAX_UPDATES_PER_HOUR count
| MAX_CONNECTIONS_PER_HOUR count
| MAX_USER_CONNECTIONS count
}
password_option: {
PASSWORD EXPIRE
| PASSWORD EXPIRE DEFAULT
| PASSWORD EXPIRE NEVER
| PASSWORD EXPIRE INTERVAL N DAY
}
lock_option: {
ACCOUNT LOCK
| ACCOUNT UNLOCK
}
首次建立用户,默认权限 USAGE = 没有权限
首次创建用户,用户是没有权限的。使用新用户链接并去查看,新用户只可以连到数据库,但是没有权限。 show grants 语句只显示具有 USAGE 权限(USAGE 就是没有权限);当然也可查看 select * from mysql.user 表。
-- 创建用户,不指定 host,则默认为 %,任意可访问
create user if not exists xxh identified by 'xiaohui';
-- 授权,可以指定列权限
-- grant select (id,name) on db_1.test_data to xiaohuihui with grant option;
-- 查看所有的用户,重点关注的是 host、user 两个字段
select * from mysql.user;
-- 刷新权限,不知道是不是我的 mysql 8,还是为什么,不需要 flush ,用户已具备权限
flush privileges;
-- 显示当前用户的权限
show grants;
授权给不存在的用户,会报错
grant select on db_1.* to xh@localhost
-- > 1410 - You are not allowed to create a user with GRANT
不同的 host 是不同的用户
-- grant select on db_1.* to xh@localhost;
select * from mysql.user;
-- create user xh@'192.168.1.59' identified by 'xiaohui';
create user if not exists xh@'192.168.0.12' identified by 'xiaohui';
结果
Host | User | Select_priv |
---|---|---|
% | xiaohui | N |
% | xiaohuihui | N |
% | xxh | N |
192.168.0.12 | xh | N |
192.168.1.59 | xh | N |
localhost | mysql.infoschema | Y |
localhost | mysql.session | N |
localhost | mysql.sys | N |
localhost | root | Y |
localhost | xiaohui | N |
删除用户
drop user xh@'192.168.0.12';
然后再次访问,就会报错 1045 - Access denied for user ‘xh’@’192.168.0.12’(using password: YES)
匿名用户
-- 本机的匿名用户
create user if not exists ''@localhost identified by '123456';
grant select on db_1.test_data to ''@'localhost';
-- 192.168.0.12 的匿名用户
create user if not exists ''@'192.168.0.12' identified by 'xiaohui';
grant select on db_1.test_data to ''@'192.168.0.12';
-- 列出了所有匿名用户:
SELECT Host, User FROM mysql.user WHERE User='';
-- 删除本地匿名用户帐户:
DROP USER ''@'localhost';
同一个 Host 同时指定用户和匿名用户时,可以乱输用户名。
只要存在匿名账户,就可以随意输入用户名,只要密码匹配,便可以进行账户对应权限的操作。
修改用户密码
alter user ''@'localhost' identified by 'xiaohui'
-- 或者SET PASSWORD 语句
SET PASSWORD [FOR user] = password_option
password_option: {
'auth_string'
| PASSWORD('auth_string')
}
-- 注意
SET PASSWORD ... = PASSWORD('auth_string') 语法在 MySQL 5.7 中已弃用,并在 MySQL 8.0 中删除。
SET PASSWORD ... = 'auth_string' 语法并未被弃用,但它ALTER USER是更改帐户(包括分配密码)的首选语句。例如:
ALTER USER user IDENTIFIED BY 'auth_string';
重名用户
RENAME USER old_user TO new_user
[, old_user TO new_user] ...
rename user xh@'%' to 'xxhh'@'%';
权限
特权 | 意义和可授予级别 |
---|---|
ALL [PRIVILEGES] | 授予指定访问级别的所有权限,除了 GRANT OPTION 和 PROXY 。 |
ALTER | 启用使用ALTER TABLE . 级别:全局、数据库、表。 |
ALTER ROUTINE | 允许更改或删除存储的例程。级别:全局、数据库、例程。 |
CREATE | 启用数据库和表创建。级别:全局、数据库、表。 |
CREATE ROUTINE | 启用存储例程创建。级别:全局、数据库。 |
CREATE TABLESPACE | 允许创建、更改或删除表空间和日志文件组。级别:全球。 |
CREATE TEMPORARY TABLES | 启用使用CREATE TEMPORARY TABLE . 级别:全局、数据库。 |
CREATE USER | 允许使用CREATE USER , DROP USER , RENAME USER ,和 REVOKE ALL PRIVILEGES 。级别:全球。 |
CREATE VIEW | 允许创建或更改视图。级别:全局、数据库、表。 |
DELETE | 启用使用DELETE . 级别:全局、数据库、表。 |
DROP | 启用要删除的数据库、表和视图。级别:全局、数据库、表。 |
EVENT | 启用事件调度程序的事件使用。级别:全局、数据库。 |
EXECUTE | 使用户能够执行存储的例程。级别:全局、数据库、例程。 |
FILE | 使用户能够使服务器读取或写入文件。级别:全球。 |
GRANT OPTION | 启用授予其他帐户或从其他帐户中删除的权限。级别:全局、数据库、表、例程、代理。 |
INDEX | 允许创建或删除索引。级别:全局、数据库、表。 |
INSERT | 启用使用INSERT . 级别:全局、数据库、表、列。 |
LOCK TABLES | 启用LOCK TABLES 对您具有SELECT 权限的表的使用。级别:全局、数据库。 |
PROCESS | 使用户能够查看带有SHOW PROCESSLIST . 级别:全球。 |
PROXY | 启用用户代理。级别:从用户到用户。 |
REFERENCES | 启用外键创建。级别:全局、数据库、表、列。 |
RELOAD | 启用FLUSH 操作。级别:全球。 |
REPLICATION CLIENT | 允许用户询问源服务器或副本服务器在哪里。级别:全球。 |
REPLICATION SLAVE | 启用副本从源读取二进制日志事件。级别:全球。 |
SELECT | 启用使用SELECT . 级别:全局、数据库、表、列。 |
SHOW DATABASES | 启用SHOW DATABASES 以显示所有数据库。级别:全球。 |
SHOW VIEW | 启用使用SHOW CREATE VIEW . 级别:全局、数据库、表。 |
SHUTDOWN | 启用mysqladmin shutdown 的 使用。级别:全球。 |
SUPER | 能够使用如其他行政业务 CHANGE MASTER TO , KILL , PURGE BINARY LOGS , SET GLOBAL ,和中mysqladmin调试 命令。级别:全球。 |
TRIGGER | 启用触发操作。级别:全局、数据库、表。 |
UPDATE | 启用使用UPDATE . 级别:全局、数据库、表、列。 |
USAGE | “无特权”的同义词 |
grant 授权,必须授予存在的用户(完整的用户是 user@xxx,就是 user表中 User@Host 组成的)
show create table mysql.user;
-- 结果
CREATE TABLE `user` (
`Host` char(255) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT '',
`User` char(32) COLLATE utf8_bin NOT NULL DEFAULT '',
`Select_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Insert_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Update_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Delete_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Create_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Drop_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Reload_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Shutdown_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Process_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`File_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Grant_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`References_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Index_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Alter_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Show_db_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Super_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Execute_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Repl_client_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Create_view_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Show_view_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Create_routine_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Create_user_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Event_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Trigger_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
`ssl_cipher` blob NOT NULL,
`x509_issuer` blob NOT NULL,
`x509_subject` blob NOT NULL,
`max_questions` int unsigned NOT NULL DEFAULT '0',
`max_updates` int unsigned NOT NULL DEFAULT '0',
`max_connections` int unsigned NOT NULL DEFAULT '0',
`max_user_connections` int unsigned NOT NULL DEFAULT '0',
`plugin` char(64) COLLATE utf8_bin NOT NULL DEFAULT 'caching_sha2_password',
`authentication_string` text COLLATE utf8_bin,
`password_expired` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`password_last_changed` timestamp NULL DEFAULT NULL,
`password_lifetime` smallint unsigned DEFAULT NULL,
`account_locked` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Create_role_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Drop_role_priv` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N',
`Password_reuse_history` smallint unsigned DEFAULT NULL,
`Password_reuse_time` smallint unsigned DEFAULT NULL,
`Password_require_current` enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`User_attributes` json DEFAULT NULL,
PRIMARY KEY (`Host`,`User`)
) /*!50100 TABLESPACE `mysql` */ ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC COMMENT='Users and global privileges'
从 mysql.user 表的主键就可以看出 user + host 才构成一个真是的账号。所有 grant 授权需要指定(Host 为 % 的除外)。
授权例子
-- 全局权限是管理权限或适用于给定服务器上的所有数据库。要分配全局权限,请使用 ON *.*语法:
GRANT ALL ON *.* TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON *.* TO 'someuser'@'somehost';
问题
- Host 是指需要连接的机器的 IP,可是多层网络或路由后,可能多台设备出去的 IP 一样,mysql 判断用户的 Host 是根据的什么呢?
关于上面问题,可以先看看 mysql 的访问控制