MySQL - 授予权限
正如我们之前所了解的,root 用户在安装 MySQL 后会立即连接到服务器(使用密码)。该用户可用的权限是默认的。使用 root 帐户访问 MySQL 的用户拥有足够的权限对数据执行基本操作。但是,在特殊情况下,用户必须手动请求主机授予权限。
MySQL 授予权限
MySQL 提供了一些 SQL 语句来允许或限制用户与数据库中存储的数据交互的管理权限。它们列示如下 -
GRANT 语句
REVOKE 语句
在本教程中,我们将详细了解 GRANT 语句。
MySQL GRANT 语句
MySQL GRANT 语句用于向 MySQL 用户帐户分配各种权限或角色。但是,需要注意的是,您不能在单个 GRANT 语句中同时分配权限和角色。要使用此语句向用户授予权限,您需要拥有 GRANT OPTION 权限。
语法
以下是 MySQL GRANT 语句的语法 -
GRANT
privilege1, privilege2, privilege3...
ON object_type
TO user_or_role1, user_or_role2, user_or_role3...
[WITH GRANT OPTION]
[AS user
[WITH ROLE
DEFAULT
| NONE
| ALL
| ALL EXCEPT role [, role ] ...
| role [, role ] ...
]
]
示例
假设我们在 MySQL 中使用 CREATE USER 语句创建了一个名为 'test_user'@'localhost' 的用户 -
CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'testpassword';
以下是上述代码的输出 -
Query OK, 0 rows affected (0.23 sec)
现在,让我们创建一个数据库 -
CREATE DATABASE test_database;
生成的输出如下 -
Query OK, 0 rows affected (0.56 sec)
接下来,我们将使用创建的数据库 -
USE test_database;
我们得到如下所示的输出 -
Database changed
现在,让我们在数据库中创建一个表 -
CREATE TABLE MyTable(data VARCHAR(255));
获得的输出如下 -
Query OK, 0 rows affected (0.67 sec)
以下查询将授予用户"test_user"@"localhost"对上述创建的表的 SELECT 权限 -
GRANT SELECT ON test_database.MyTable TO 'test_user'@'localhost';
执行上述代码后,我们得到以下输出 -
Query OK, 0 rows affected (0.31 sec)
验证
您可以使用 SHOW GRANTS 语句验证已授予的权限 -
SHOW GRANTS FOR 'test_user'@'localhost';
我们得到的输出如下所示 -
| Grants for test_user@localhost |
|---|
| GRANT USAGE ON *.* TO `test_user`@`localhost` |
| GRANT SELECT ON `test_database`.`mytable` TO `test_user`@`localhost` |
授予各种权限
我们知道,MySQL GRANT 语句可以授予用户帐户各种权限。以下是一些可以使用 GRANT 语句授予的常用权限列表 -
| 权限 | 说明 |
|---|---|
| ALTER | 允许用户使用 ALTER TABLE 语句修改表结构。 |
| CREATE | 授予创建新对象(例如表和数据库)的权限。 |
| DELETE | 允许用户从中删除行表。 |
| INSERT | 允许用户在表中插入新记录。 |
| SELECT | 提供对表的读取权限,允许用户检索数据。 |
| UPDATE | 允许用户修改表中的现有数据。 |
| SHOW DATABASES | 授予查看可用数据库列表的权限。 |
| CREATE USER | 允许用户创建新的 MySQL 用户帐户。 |
| GRANT OPTION | 为用户提供并有权向其他用户授予权限。 |
| SUPER | 授予高级管理权限。 |
| SHUTDOWN | 允许用户关闭 MySQL 服务器。 |
| REPLICATION CLIENT | 提供对复制相关信息的访问权限。 |
| REPLICATION SLAVE | 允许用户充当复制从属服务器。 |
| FILE | 授予在服务器文件系统上读写文件的权限。 |
| CREATE VIEW | 允许用户创建新的数据库视图。 |
| CREATE TEMPORARY TABLES | 允许创建临时表。 |
| EXECUTE | 允许用户执行存储过程和函数。 |
| TRIGGER | 提供创建和管理触发器的能力。 |
| EVENT | 授予创建和管理事件的能力。 |
| SHOW VIEW | 允许用户查看视图。 |
| INDEX | 允许用户在表上创建和删除索引。 |
| PROXY | 提供代理或模拟其他用户的功能。 |
要授予用户所有可用权限,您需要在 GRANT 语句中使用"ALL"关键字 -
GRANT ALL ON test_database.MyTable TO 'test_user'@'localhost';输出
执行上述代码后,我们得到以下输出 -
Query OK, 0 rows affected (0.13 sec)
授予存储例程的权限
要在 MySQL 中授予存储例程(例如表、过程或函数)的权限,您需要在 ON 子句后指定对象类型(PROCEDURE 或 FUNCTION),后跟例程的名称。
您可以授予这些存储例程的 ALTER ROUTINE、CREATE ROUTINE、EXECUTE 和 GRANT OPTION 权限。
示例
假设我们在当前数据库中创建了一个名为"sample"的存储过程和存储函数,如下所示 -
//创建一个过程
DELIMITER //
CREATE PROCEDURE sample ()
BEGIN
SELECT 'This is a sample procedure';
END//
Query OK, 0 rows affected (0.29 sec)
//Creating a function
CREATE FUNCTION sample()
RETURNS VARCHAR(120)
DETERMINISTIC
BEGIN
DECLARE val VARCHAR(120);
SET val = 'This is a sample function';
return val;
END//
DELIMITER ;
以下是获得的输出 -
Query OK, 0 rows affected (0.34 sec)
创建这些存储例程后,您可以向名为 'test_user'@'localhost' 的用户授予上述创建过程的 ALTER ROUTINE、EXECUTE 权限,如下所示 -
GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE test_database.sample TO 'test_user'@'localhost';
生成的输出如下所示 -
Query OK, 0 rows affected (0.24 sec)
现在,以下查询将上述创建的函数的 ALTER ROUTINE, EXECUTE 权限授予名为 'test_user'@'localhost' 的用户。
GRANT ALTER ROUTINE, EXECUTE ON FUNCTION test_database.sample TO 'test_user'@'localhost';
以下是上述查询的输出 -
Query OK, 0 rows affected (0.15 sec)
授予多个用户的权限
您可以向多个用户授予权限。为此,您需要提供对象或用户的名称,并以逗号分隔。
示例
假设我们使用如下所示的 CREATE 语句创建了一个名为"sample"的表和三个用户帐户。
创建表 -
CREATE TABLE sample (data VARCHAR(255));
我们将得到如下所示的输出 -
查询成功,0 行受影响(3.55 秒)
现在,让我们创建用户帐户。
创建用户"test_user1"-
CREATE USER test_user1 IDENTIFIED BY 'testpassword';
获得的输出如下 −
Query OK, 0 rows affected (0.77 sec)
创建用户"test_user2" -
CREATE USER test_user2 IDENTIFIED BY 'testpassword';
以下是生成的输出 -
Query OK, 0 rows affected (0.28 sec)
创建第三个用户 −
创建用户"test_user3" −
CREATE USER test_user3 IDENTIFIED BY 'testpassword';
我们得到如下输出 −
Query OK, 0 rows affected (0.82 sec)
以下查询使用单个 GRANT 语句向所有三个用户("test_user1"、"test_user2"和"test_user3")授予对表"sample1"、"sample2"和"sample3"的 SELECT、INSERT 和 UPDATE 权限。
GRANT SELECT, INSERT, UPDATE ON TABLE sample TO test_user1, test_user2, test_user3;
输出
执行上述代码后,我们得到以下输出 -
Query OK, 0 rows affected (0.82 sec)
全局权限
您可以授予全局权限,而无需指定表、过程或函数:即适用于所有数据库的权限。为此,您需要在 ON 子句后使用 *.*。
示例
以下查询将向名为"test_user"@"localhost"的用户授予所有数据库的 SELECT、INSERT 和 UPDATE 权限 -
GRANT SELECT, INSERT, UPDATE ON *.* TO 'test_user'@'localhost';
输出
以下是获得的输出 -
Query OK, 0 rows affected (0.43 sec)
示例
类似地,以下查询将所有数据库的所有权限授予 'test_user'@'localhost -
GRANT ALL ON *.* TO 'test_user'@'localhost';
输出
生成的输出如下所示 -
Query OK, 0 rows affected (0.41 sec)
数据库级别权限
您可以通过在 ON 子句后指定数据库名称并加上".*"来授予数据库中所有对象的权限。
示例
以下查询将授予用户"test_user"@"localhost"对名为 test 的数据库中所有对象的 SELECT、INSERT 和 UPDATE 权限 -
GRANT SELECT, INSERT, UPDATE ON test.* TO 'test_user'@'localhost';
输出
以下是上述代码的输出 -
Query OK, 0 rows affected (0.34 sec)
示例
类似地,以下查询将所有数据库的所有权限授予 'test_user'@'localhost -
GRANT ALL ON test.* TO 'test_user'@'localhost';
输出
上述代码的输出如下 -
Query OK, 0 rows affected (0.54 sec)
列级权限
您可以向用户授予表中特定列的权限。为此,您需要在权限后指定列名。
示例
假设我们使用 CREATE 查询创建了一个名为 Employee 的表,如下所示:-
CREATE TABLE Employee ( ID INT, Name VARCHAR(15), Phone INT, SAL INT);
生成的输出如下所示:-
Query OK, 0 rows affected (6.47 sec)
以下查询授予名为 'test_user'@'localhost' 的用户在 ID 列上的 SELECT 权限,以及在 Employee 表的 Name 和 Phone 列上的 INSERT 和 UPDATE 权限 -
GRANT SELECT (ID), INSERT (Name, Phone) ON Employee TO 'test_user'@'localhost';
获得的输出如下 −
Query OK, 0 rows affected (0.54 sec)
代理用户权限
您可以通过授予一个用户 PROXY 权限,使其成为另一个用户的代理。这样做后,两个用户将拥有相同的权限。
示例
假设我们在 MySQL 中使用 CREATE 语句创建了一个名为 sample_user, proxy_user 的用户,如下所示 -
CREATE USER sample_user, proxy_user IDENTIFIED BY 'testpassword';
以下是获得的输出 -
Query OK, 0 rows affected (0.52 sec)
以下查询将上面创建的 Employee 表的 SELECT 和 INSERT 权限授予用户 sample_user -
GRANT SELECT, INSERT ON Emp TO sample_user;
我们得到如下所示的输出 -
Query OK, 0 rows affected (0.28 sec)
现在,我们可以使用 GRANT 语句为用户 proxy_user 分配代理权限,如下所示 -
GRANT PROXY ON sample_user TO proxy_user;
输出如下 -
Query OK, 0 rows affected (1.61 sec)
授予角色
MySQL 中的角色是一组具有名称的权限。您可以使用 CREATE ROLE 语句在 MySQL 中创建一个或多个角色。如果使用不带 ON 子句的 GRANT 语句,则可以授予角色而不是权限。
示例
我们首先创建一个名为 TestRole_ReadOnly 的角色。
CREATE ROLE 'TestRole_ReadOnly';
以下是获得的输出 -
Query OK, 0 rows affected (0.13 sec)
现在,让我们使用 GRANT 语句向创建的角色授予访问数据库中所有对象的只读权限 -
GRANT SELECT ON * . * TO 'TestRole_ReadOnly';
此 GRANT 语句的输出应为 -
Query OK, 0 rows affected (0.14 sec)
然后,您可以将创建的角色授予特定用户。首先,您需要按如下所示创建用户 -
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
以下是生成的输出 -
Query OK, 0 rows affected (0.14 sec)
现在,您可以将"TestRole_ReadOnly"角色授予"newuser"@"localhost" -
GRANT 'TestRole_ReadOnly' TO 'newuser'@'localhost';
获得的输出如下所示 -
Query OK, 0 rows affected (0.13 sec)
使用客户端程序授予权限
现在,让我们看看如何使用客户端程序向 MySQL 用户授予权限。
语法
以下是语法 -
要使用 PHP 程序向 MySQL 数据库中的用户授予所有权限,我们需要执行 GRANT ALL 语句,如下所示 -
$sql = "GRANT ALL PRIVILEGES ON database_name.* TO 'username'@'localhost'"; $mysqli->query($sql);
以下是使用 JavaScript 程序向所需用户授予特定权限的语法 -
sql= "GRANT privilege_name(s) ON object TO user_account_name";
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
});
要在 MySQL 数据库中授予权限,我们需要使用 JDBC execute() 函数执行 GRANT ALL PRIVILEGES 语句,如下所示:-
String sql = "GRANT ALL PRIVILEGES ON DATABASE_NAME.* TO 'USER_NAME'@'localhost'"; statement.execute(sql);
以下是使用 Python 程序向所需用户授予特定权限的语法 -
sql = f"GRANT {privileges} ON your_database.* TO '{username_to_grant}'@'localhost'";
cursorObj.execute(sql);
示例
以下是程序 -
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'password';
$mysqli = new mysqli($dbhost, $dbuser, $dbpass);
if($mysqli->connect_errno ) {
printf("Connect failed: %s
", $mysqli->connect_error);
exit();
}
//printf('Connected successfully.
');
$sql = "GRANT ALL PRIVILEGES ON tutorials.* TO 'Revathi'@'localhost'";
if($result = $mysqli->query($sql)){
printf("Grant privileges executed successfully...!");
}
if($mysqli->error){
printf("Failed..!" , $mysqli->error);
}
$mysqli->close();
输出
获得的输出如下 -
Grant privileges executed successfully...!
var mysql = require('mysql2');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "Nr5a0204@123" });
//连接到 MySQL
con.connect(function (err) {
if (err) throw err;
console.log("Connected!");
console.log("--------------------------");
sql = "CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'testpassword';"
con.query(sql);
sql = "CREATE DATABASE test_database;"
con.query(sql);
sql = "USE test_database;"
con.query(sql);
sql = "CREATE TABLE MyTable(data VARCHAR(255));"
con.query(sql);
sql = "GRANT SELECT ON test_database.MyTable TO 'test_user'@'localhost';"
con.query(sql);
sql = "SHOW GRANTS FOR 'test_user'@'localhost';";
con.query(sql, function(err, result){
if (err) throw err;
console.log(result);
});
});
输出
生成的输出如下 -
Connected!
--------------------------
[
{
'Grants for test_user@localhost': 'GRANT USAGE ON *.* TO `test_user`@`localhost`'
},
{
'Grants for test_user@localhost': 'GRANT SELECT ON `test_database`.`mytable` TO `test_user`@`localhost`'
}
]
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class GranPriv {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/TUTORIALS";
String user = "root";
String password = "password";
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection con = DriverManager.getConnection(url, user, password);
Statement st = con.createStatement();
//System.out.println("Database connected successfully...!");
String sql = "GRANT ALL PRIVILEGES ON tutorials.* TO 'Vivek'@'localhost'";
st.execute(sql);
System.out.println("You grant all privileges to user 'Vivek'...!");
}catch(Exception e) {
e.printStackTrace();
}
}
}
输出
获得的输出如下所示 -
You grant all privileges to user 'Vivek'...!
import mysql.connector
# creating the connection object
connection = mysql.connector.connect(
host='localhost',
user='root',
password='password'
)
username_to_grant = 'newUser'
# privileges we want to grant
privileges = 'SELECT, INSERT, UPDATE'
# Create a cursor object for the connection
cursorObj = connection.cursor()
cursorObj.execute(f"GRANT {privileges} ON your_database.* TO '{username_to_grant}'@'localhost'")
print(f"Privileges granted to user '{username_to_grant}' successfully.")
cursorObj.close()
connection.close()
输出
以下是上述代码的输出 -
Privileges granted to user 'newUser' successfully.

