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 8.2.4, “Specifying Account Names”)
| role (see Section 8.2.5, “Specifying Role Names”)
}
GRANT
陳述式會將權限和角色指派給 MySQL 使用者帳戶和角色。GRANT
陳述式有數個方面,將在下列主題中說明:
GRANT
陳述式可讓系統管理員授與權限和角色,這些權限和角色可以授與使用者帳戶和角色。下列是適用的語法限制:
如需有關角色的詳細資訊,請參閱第 8.2.10 節「使用角色」。
若要使用 GRANT
授與權限,您必須具有 GRANT OPTION
權限,並且必須具有您正在授與的權限。(或者,如果您具有 mysql
系統結構描述中授與表格的 UPDATE
權限,則可以授與任何帳戶任何權限。)啟用 read_only
系統變數時,GRANT
還需要 CONNECTION_ADMIN
權限 (或已棄用的 SUPER
權限)。
GRANT
會針對所有具名的使用者和角色成功,如果發生任何錯誤,則會回復且不會生效。只有當陳述式針對所有具名的使用者和角色成功時,才會寫入二進位日誌。
REVOKE
陳述式與 GRANT
有關,並讓管理員能夠移除帳戶權限。請參閱第 15.7.1.8 節「REVOKE 陳述式」。
每個帳戶名稱都使用第 8.2.4 節「指定帳戶名稱」中所述的格式。每個角色名稱都使用第 8.2.5 節「指定角色名稱」中所述的格式。例如:
GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
GRANT SELECT ON world.* TO 'role3';
如果省略帳戶或角色名稱的主機名稱部分,則預設為 '%'
。
通常,資料庫管理員會先使用 CREATE USER
來建立帳戶,並定義其非權限特性,例如其密碼、是否使用安全連線以及存取伺服器資源的限制,然後使用 GRANT
來定義其權限。可以使用 ALTER USER
來變更現有帳戶的非權限特性。例如:
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 程式,當 GRANT
成功執行時,會以 Query OK, 0 rows affected
回應。若要判斷作業產生的權限為何,請使用 SHOW GRANTS
。請參閱第 15.7.7.22 節「SHOW GRANTS 陳述式」。
在某些情況下,GRANT
可能會記錄在伺服器日誌中,或記錄在用戶端中,如 ~/.mysql_history
等歷史記錄檔中,這表示任何有權讀取該資訊的人都可以讀取明文密碼。如需瞭解伺服器日誌發生此情況的條件以及如何控制,請參閱第 8.1.2.3 節「密碼和記錄」。如需瞭解用戶端記錄的類似資訊,請參閱第 6.5.1.3 節「mysql 用戶端記錄」。
GRANT
支援長度最多 255 個字元的主機名稱。使用者名稱最多可為 32 個字元。資料庫、資料表、欄位和常式名稱最多可為 64 個字元。
請勿嘗試透過變更 mysql.user
系統表格來變更使用者名稱允許的長度。這樣做會導致無法預期的行為,甚至可能導致使用者無法登入 MySQL 伺服器。除了第 3 章「升級 MySQL」中所述的程序之外,絕不要以任何方式變更 mysql
系統結構描述中表格的結構。
GRANT
陳述式中的數個物件都需要引用,雖然在許多情況下引用是選擇性的:帳戶、角色、資料庫、資料表、欄位和常式名稱。例如,如果帳戶名稱中的 user_name
或 host_name
值可以作為未引用的識別碼,則您不需要引用它。不過,必須使用引號來指定包含特殊字元 (例如 -
) 的 user_name
字串,或包含特殊字元或萬用字元 (例如 %
) 的 host_name
字串 (例如,'test-user'@'%.com'
)。請分別引用使用者名稱和主機名稱。
若要指定引用的值:
請將資料庫、資料表、欄位和常式名稱引用為識別碼。
請將使用者名稱和主機名稱引用為識別碼或字串。
請將密碼引用為字串。
如需字串引用和識別碼引用準則,請參閱第 11.1.1 節「字串常值」和第 11.2 節「結構描述物件名稱」。
在接下來的段落中描述的萬用字元 %
和 _
的使用已棄用,因此可能會在 MySQL 的未來版本中移除。
當在 GRANT
陳述式中指定資料庫層級的權限時 (GRANT ... ON
),允許使用 db_name
.*_
和 %
萬用字元。這表示,例如,若要使用 _
字元作為資料庫名稱的一部分,請在 GRANT
陳述式中使用 \
跳脫字元,將其指定為 \_
,以防止使用者能夠存取其他符合萬用字元模式的資料庫 (例如,GRANT ... ON `foo\_bar`.* TO ...
)。
發出多個包含萬用字元的 GRANT
陳述式可能不會對 DML 陳述式產生預期的效果;當解析包含萬用字元的授與時,MySQL 只會考慮第一個符合的授與。換句話說,如果使用者有兩個使用萬用字元且符合相同資料庫的資料庫層級授與,則會套用首先建立的授與。請考慮使用此處顯示的陳述式建立的資料庫 db
和資料表 t
:
mysql> CREATE DATABASE db;
Query OK, 1 row affected (0.01 sec)
mysql> CREATE TABLE db.t (c INT);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO db.t VALUES ROW(1);
Query OK, 1 row affected (0.00 sec)
接下來 (假設目前帳戶是 MySQL root
帳戶或另一個具有必要權限的帳戶),我們建立使用者 u
,然後發出兩個包含萬用字元的 GRANT
陳述式,如下所示:
mysql> CREATE USER u;
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT SELECT ON `d_`.* TO u;
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT INSERT ON `d%`.* TO u;
Query OK, 0 rows affected (0.00 sec)
mysql> EXIT
Bye
如果我們結束工作階段,然後使用 mysql 用戶端再次登入,這次以 u 登入,我們可以看到此帳戶僅具有第一個符合授與所提供的權限,但沒有第二個授與:
$> mysql -uu -hlocalhost
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 9.1.0-tr Source distribution
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input
statement.
mysql> TABLE db.t;
+------+
| c |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> INSERT INTO db.t VALUES ROW(2);
ERROR 1142 (42000): INSERT command denied to user 'u'@'localhost' for table 't'
在權限指派中,在下列情況下,MySQL 會將資料庫名稱中未跳脫的 _
和 %
SQL 萬用字元視為常值字元:
當資料庫名稱不是用於授與資料庫層級的權限,而是用於限定授與其他物件 (例如資料表或常式) 的權限時 (例如,
GRANT ... ON
)。db_name
.tbl_name
啟用
partial_revokes
會導致 MySQL 將資料庫名稱中未跳脫的_
和%
萬用字元視為常值字元,就像它們已跳脫為\_
和\%
一樣。由於這會變更 MySQL 解譯權限的方式,因此建議在可能啟用partial_revokes
的安裝中,避免在權限指派中使用未跳脫的萬用字元。如需詳細資訊,請參閱第 8.2.12 節「使用部分撤銷的權限限制」。
GRANT
陳述式中的 user
值表示此陳述式適用的 MySQL 帳戶。為了容納從任意主機授與權限給使用者,MySQL 支援以 '
的形式指定 user_name
'@'host_name
'user
值。
您可以在主機名稱中指定萬用字元。例如,'
適用於 user_name
'@'%.example.com'example.com
網域中任何主機的 user_name
,而 '
適用於 user_name
'@'198.51.100.%'198.51.100
C 類子網路中任何主機的 user_name
。
簡化的形式 '
是 user_name
''
的同義詞。user_name
'@'%'
MySQL 會自動將授予 '
的所有權限也授予 username
'@'%''
帳戶。此行為已被棄用,並可能在未來的 MySQL 版本中移除。username
'@'localhost'
MySQL 不支援使用者名稱中的萬用字元。若要參照匿名使用者,請使用 GRANT
陳述式指定一個使用者名稱為空的帳戶
GRANT ALL ON test.* TO ''@'localhost' ...;
在這種情況下,任何從本機主機連線且具有匿名使用者正確密碼的使用者都允許存取,並擁有與匿名使用者帳戶相關聯的權限。
關於帳戶名稱中的使用者名稱和主機名稱值的更多資訊,請參閱 第 8.2.4 節「指定帳戶名稱」。
如果您允許本機匿名使用者連線到 MySQL 伺服器,您也應該將權限授予所有本機使用者,形式為 '
。否則,當具名使用者嘗試從本機登入 MySQL 伺服器時,會使用 user_name
'@'localhost'mysql.user
系統表格中 localhost
的匿名使用者帳戶。詳細資訊請參閱 第 8.2.6 節「存取控制,階段 1:連線驗證」。
要判斷此問題是否適用於您,請執行以下查詢,它會列出所有匿名使用者
SELECT Host, User FROM mysql.user WHERE User='';
要避免剛才描述的問題,請使用以下陳述式刪除本機匿名使用者帳戶
DROP USER ''@'localhost';
下表總結了可以為 GRANT
和 REVOKE
陳述式指定的允許的靜態和動態 priv_type
權限類型,以及每個權限可以被授予的層級。關於每個權限的更多資訊,請參閱 第 8.2.2 節「MySQL 提供的權限」。關於靜態權限和動態權限之間的差異,請參閱 靜態權限與動態權限。
表 15.11 GRANT 和 REVOKE 允許的靜態權限
權限 | 含義和可授予的層級 |
---|---|
ALL [PRIVILEGES] |
在指定存取層級授予所有權限,除了 GRANT OPTION 和 PROXY 。 |
ALTER |
啟用 ALTER TABLE 的使用。層級:全域、資料庫、表格。 |
ALTER ROUTINE |
啟用儲存程序被變更或刪除。層級:全域、資料庫、程序。 |
CREATE |
啟用資料庫和表格的建立。層級:全域、資料庫、表格。 |
CREATE ROLE |
啟用角色的建立。層級:全域。 |
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 |
啟用資料庫、表格和檢視表的刪除。層級:全域、資料庫、表格。 |
DROP ROLE |
啟用角色的刪除。層級:全域。 |
EVENT |
啟用事件排程器的事件使用。層級:全域、資料庫。 |
EXECUTE |
啟用使用者執行儲存程序。層級:全域、資料庫、程序。 |
FILE |
啟用使用者使伺服器讀取或寫入檔案。層級:全域。 |
FLUSH_PRIVILEGES |
啟用使用者發出 FLUSH PRIVILEGES 陳述式。層級:全域。 |
GRANT OPTION |
啟用將權限授予其他帳戶或從其他帳戶移除權限。層級:全域、資料庫、表格、程序、代理。 |
INDEX |
啟用索引的建立或刪除。層級:全域、資料庫、表格。 |
INSERT |
啟用 INSERT 的使用。層級:全域、資料庫、表格、欄位。 |
LOCK TABLES |
啟用對您擁有 SELECT 權限的表格使用 LOCK TABLES 。層級:全域、資料庫。 |
OPTIMIZE_LOCAL_TABLE |
啟用 OPTIMIZE LOCAL TABLE 或 OPTIMIZE NO_WRITE_TO_BINLOG TABLE 的使用。層級:全域、資料庫、表格。 |
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 REPLICATION SOURCE TO 、KILL 、PURGE BINARY LOGS 、SET GLOBAL 和 mysqladmin debug 命令。層級:全域。 |
TRIGGER |
啟用觸發程序操作。層級:全域、資料庫、表格。 |
UPDATE |
啟用 UPDATE 的使用。層級:全域、資料庫、表格、欄位。 |
USAGE |
「沒有權限」的同義詞 |
表 15.12 GRANT 和 REVOKE 允許的動態權限
權限 | 含義和可授予的層級 |
---|---|
APPLICATION_PASSWORD_ADMIN |
啟用雙密碼管理。層級:全域。 |
AUDIT_ABORT_EXEMPT |
允許被稽核日誌篩選器封鎖的查詢。層級:全域。 |
AUDIT_ADMIN |
啟用稽核日誌設定。層級:全域。 |
AUTHENTICATION_POLICY_ADMIN |
啟用驗證策略管理。層級:全域。 |
BACKUP_ADMIN |
啟用備份管理。層級:全域。 |
BINLOG_ADMIN |
啟用二進位日誌控制。層級:全域。 |
BINLOG_ENCRYPTION_ADMIN |
啟用二進位日誌加密的啟用和停用。層級:全域。 |
CLONE_ADMIN |
啟用複製管理。層級:全域。 |
CONNECTION_ADMIN |
啟用連線限制/限制控制。層級:全域。 |
ENCRYPTION_KEY_ADMIN |
啟用 InnoDB 金鑰輪換。層級:全域。 |
FIREWALL_ADMIN |
啟用防火牆規則管理,任何使用者。層級:全域。 |
FIREWALL_EXEMPT |
豁免使用者不受防火牆限制。層級:全域。 |
FIREWALL_USER |
啟用防火牆規則管理,自身。層級:全域。 |
FLUSH_OPTIMIZER_COSTS |
啟用最佳化工具成本重新載入。層級:全域。 |
FLUSH_STATUS |
啟用狀態指示器刷新。層級:全域。 |
FLUSH_TABLES |
啟用表格刷新。層級:全域。 |
FLUSH_USER_RESOURCES |
啟用使用者資源刷新。層級:全域。 |
GROUP_REPLICATION_ADMIN |
啟用群組複寫控制。層級:全域。 |
INNODB_REDO_LOG_ARCHIVE |
啟用重做日誌封存管理。層級:全域。 |
INNODB_REDO_LOG_ENABLE |
啟用或停用重做記錄。層級:全域。 |
NDB_STORED_USER |
啟用 SQL 節點 (NDB Cluster) 之間的使用者或角色共享。層級:全域。 |
PASSWORDLESS_USER_ADMIN |
啟用無密碼使用者帳戶管理。層級:全域。 |
PERSIST_RO_VARIABLES_ADMIN |
啟用持久化唯讀系統變數。層級:全域。 |
REPLICATION_APPLIER |
充當複寫通道的 PRIVILEGE_CHECKS_USER 。層級:全域。 |
REPLICATION_SLAVE_ADMIN |
啟用常規複寫控制。層級:全域。 |
RESOURCE_GROUP_ADMIN |
啟用資源群組管理。層級:全域。 |
RESOURCE_GROUP_USER |
啟用資源群組管理。層級:全域。 |
ROLE_ADMIN |
啟用角色的授與或撤銷,使用 WITH ADMIN OPTION 。層級:全域。 |
SESSION_VARIABLES_ADMIN |
啟用設定受限制的工作階段系統變數。層級:全域。 |
SHOW_ROUTINE |
啟用存取已儲存的常式定義。層級:全域。 |
SKIP_QUERY_REWRITE |
不要改寫此使用者執行的查詢。層級:全域。 |
SYSTEM_USER |
將帳戶指定為系統帳戶。層級:全域。 |
SYSTEM_VARIABLES_ADMIN |
啟用修改或持續保存全域系統變數。層級:全域。 |
TABLE_ENCRYPTION_ADMIN |
啟用覆寫預設加密設定。層級:全域。 |
TELEMETRY_LOG_ADMIN |
啟用 AWS 上 HeatWave 的遙測記錄組態。層級:全域。 |
TP_CONNECTION_ADMIN |
啟用執行緒池連線管理。層級:全域。 |
VERSION_TOKEN_ADMIN |
啟用版本符記功能的使用。層級:全域。 |
XA_RECOVER_ADMIN |
啟用 XA RECOVER 執行。層級:全域。 |
觸發程序與資料表相關聯。若要建立或捨棄觸發程序,您必須具有資料表的 TRIGGER
權限,而不是觸發程序的權限。
在 GRANT
陳述式中,ALL [PRIVILEGES]
或 PROXY
權限必須單獨命名,且不能與其他權限一起指定。ALL [PRIVILEGES]
代表在要授與權限的層級可用的所有權限,但 GRANT OPTION
和 PROXY
權限除外。
MySQL 帳戶資訊儲存在 mysql
系統綱要的資料表中。如需更多詳細資訊,請參閱 第 8.2 節「存取控制和帳戶管理」,其中廣泛討論了 mysql
系統綱要和存取控制系統。
如果授與資料表包含包含大小寫混合的資料庫或資料表名稱的權限列,且 lower_case_table_names
系統變數設定為非零值,則無法使用 REVOKE
撤銷這些權限。在這種情況下,必須直接操作授與資料表。(當 lower_case_table_names
設定時,GRANT
不會建立這類列,但可能在設定該變數之前已建立這類列。lower_case_table_names
設定只能在伺服器啟動時設定。)
可以根據用於 ON
子句的語法,在多個層級授與權限。對於 REVOKE
,相同的 ON
語法會指定要移除的權限。
對於全域、資料庫、資料表和常式層級,GRANT ALL
只會指派您要授與的層級上存在的權限。例如,GRANT ALL ON
是資料庫層級陳述式,因此它不會授與任何僅限全域的權限,例如 db_name
.*FILE
。授與 ALL
不會指派 GRANT OPTION
或 PROXY
權限。
如果存在 object_type
子句,當以下物件是資料表、已儲存的函數或已儲存的程序時,應該指定為 TABLE
、FUNCTION
或 PROCEDURE
。
使用者針對資料庫、資料表、資料行或常式擁有的權限是以累加方式,形成每個權限層級的帳戶權限的邏輯 OR
,包括全域層級。無法藉由較低層級缺少該權限來拒絕較高層級授與的權限。例如,此陳述式會全域授與 SELECT
和 INSERT
權限
GRANT SELECT, INSERT ON *.* TO u1;
全域授與的權限適用於所有資料庫、資料表和資料行,即使未在任何較低的層級授與也是如此。
如果啟用 partial_revokes
系統變數,則可以藉由撤銷特定資料庫的權限來明確拒絕全域層級授與的權限
GRANT SELECT, INSERT, UPDATE ON *.* TO u1;
REVOKE INSERT, UPDATE ON db1.* FROM u1;
前述陳述式的結果是,SELECT
全域適用於所有資料表,而 INSERT
和 UPDATE
全域適用,但 db1
中的資料表除外。db1
的帳戶存取權是唯讀的。
權限檢查程序的詳細資訊在 第 8.2.7 節「存取控制,階段 2:要求驗證」中提供。
如果您為一個使用者使用資料表、資料行或常式權限,伺服器會檢查所有使用者的資料表、資料行和常式權限,這會稍微減慢 MySQL 的速度。同樣地,如果您限制任何使用者的查詢、更新或連線數量,伺服器必須監控這些值。
MySQL 可讓您授與不存在的資料庫或資料表的權限。對於資料表,要授與的權限必須包括 CREATE
權限。此行為是設計使然,目的是讓資料庫管理員能夠為稍後建立的資料庫或資料表準備使用者帳戶和權限。
當您捨棄資料庫或資料表時,MySQL 不會自動撤銷任何權限。但是,如果您捨棄常式,則會撤銷針對該常式授與的任何常式層級權限。
全域權限是管理性的,或適用於給定伺服器上的所有資料庫。若要指派全域權限,請使用 ON *.*
語法
GRANT ALL ON *.* TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON *.* TO 'someuser'@'somehost';
CREATE TABLESPACE
、CREATE USER
、FILE
、PROCESS
、RELOAD
、REPLICATION CLIENT
、REPLICATION SLAVE
、SHOW DATABASES
、SHUTDOWN
和 SUPER
靜態權限是管理性的,且只能全域授與。
動態權限都是全域的,且只能全域授與。
其他權限可以在全域或更特定的層級授與。
在全域層級授與的 GRANT OPTION
的效果對於靜態和動態權限有所不同
針對任何靜態全域權限授與的
GRANT OPTION
適用於所有靜態全域權限。針對任何動態權限授與的
GRANT OPTION
僅適用於該動態權限。
全域層級的 GRANT ALL
會授與所有靜態全域權限和所有目前已註冊的動態權限。GRANT
陳述式執行後註冊的動態權限不會追溯授與任何帳戶。
MySQL 將全域權限儲存在 mysql.user
系統資料表中。
資料庫權限適用於給定資料庫中的所有物件。若要指派資料庫層級權限,請使用 ON
語法db_name
.*
GRANT ALL ON mydb.* TO 'someuser'@'somehost';
GRANT SELECT, INSERT ON mydb.* TO 'someuser'@'somehost';
如果您使用 ON *
語法(而不是 ON *.*
),權限會在預設資料庫的資料庫層級指派。如果沒有預設資料庫,則會發生錯誤。
CREATE
、DROP
、EVENT
、GRANT OPTION
、LOCK TABLES
和 REFERENCES
權限可以在資料庫層級指定。資料表或常式權限也可以在資料庫層級指定,在這種情況下,它們適用於資料庫中的所有資料表或常式。
MySQL 將資料庫權限儲存在 mysql.db
系統資料表中。
資料表權限適用於給定資料表中的所有資料行。若要指派資料表層級權限,請使用 ON
語法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
值為 ALTER
、CREATE VIEW
、CREATE
、DELETE
、DROP
、GRANT OPTION
、INDEX
、INSERT
、REFERENCES
、SELECT
、SHOW VIEW
、TRIGGER
和 UPDATE
。
資料表層級權限適用於基礎資料表和檢視。它們不適用於使用 CREATE TEMPORARY TABLE
建立的資料表,即使資料表名稱相符也是如此。如需有關 TEMPORARY
資料表權限的資訊,請參閱 第 15.1.20.2 節「CREATE TEMPORARY TABLE 陳述式」。
MySQL 將資料表權限儲存在 mysql.tables_priv
系統資料表中。
欄位權限適用於指定表格中的單一欄位。在欄位層級授予的每個權限都必須後接括號內的欄位或多個欄位。
GRANT SELECT (col1), INSERT (col1, col2) ON mydb.mytbl TO 'someuser'@'somehost';
欄位的可允許 priv_type
值(也就是當您使用 column_list
子句時)為 INSERT
、REFERENCES
、SELECT
和 UPDATE
。
MySQL 將欄位權限儲存在 mysql.columns_priv
系統表格中。
ALTER ROUTINE
、CREATE ROUTINE
、EXECUTE
和 GRANT OPTION
權限適用於預存常式(程序和函式)。它們可以在全域和資料庫層級授予。除了 CREATE ROUTINE
之外,這些權限可以在個別常式的常式層級授予。
GRANT CREATE ROUTINE ON mydb.* TO 'someuser'@'somehost';
GRANT EXECUTE ON PROCEDURE mydb.myproc TO 'someuser'@'somehost';
常式層級的可允許 priv_type
值為 ALTER ROUTINE
、EXECUTE
和 GRANT OPTION
。CREATE ROUTINE
不是常式層級的權限,因為您必須先在全域或資料庫層級擁有該權限才能建立常式。
MySQL 將常式層級權限儲存在 mysql.procs_priv
系統表格中。
PROXY
權限可讓一個使用者成為另一個使用者的代理。代理使用者會模擬或取得被代理使用者的身分;也就是說,它會承擔被代理使用者的權限。
GRANT PROXY ON 'localuser'@'localhost' TO 'externaluser'@'somehost';
當授予 PROXY
時,它必須是 GRANT
陳述式中唯一指定的權限,而唯一允許的 WITH
選項是 WITH GRANT OPTION
。
使用代理需要代理使用者透過外掛程式進行驗證,該外掛程式會在代理使用者連線時將被代理使用者的名稱傳回伺服器,並且代理使用者必須擁有被代理使用者的 PROXY
權限。如需詳細資訊和範例,請參閱第 8.2.19 節,「代理使用者」。
MySQL 將代理權限儲存在 mysql.proxies_priv
系統表格中。
沒有 ON
子句的 GRANT
語法會授予角色,而不是個別的權限。角色是權限的命名集合;請參閱第 8.2.10 節,「使用角色」。例如
GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
要授予的每個角色以及要授予的每個使用者帳戶或角色都必須存在。角色不能授予給匿名使用者。
授予角色不會自動導致該角色處於作用中狀態。有關角色啟用和停用的資訊,請參閱啟用角色。
授予角色需要以下權限
如果您擁有
ROLE_ADMIN
權限(或已棄用的SUPER
權限),您可以將任何角色授予或撤銷給使用者或角色。如果您被授予包含
WITH ADMIN OPTION
子句的GRANT
陳述式角色,您將能夠將該角色授予其他使用者或角色,或從其他使用者或角色撤銷該角色,只要該角色在您後續授予或撤銷時處於作用中狀態即可。這包括使用WITH ADMIN OPTION
本身的能力。若要授予具有
SYSTEM_USER
權限的角色,您必須擁有SYSTEM_USER
權限。
可以使用 GRANT
建立循環參考。例如
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
允許循環授予參考,但不會為被授予者新增任何新的權限或角色,因為使用者或角色已擁有其權限和角色。
GRANT
可以使用 AS
子句指定有關用於執行陳述式的權限內容的其他資訊。此語法在 SQL 層級可見,但其主要目的是通過導致這些限制出現在二進位記錄中,以實現跨所有節點的授予者權限限制(由部分撤銷所施加)的統一複製。有關部分撤銷的資訊,請參閱第 8.2.12 節,「使用部分撤銷的權限限制」。user
[WITH ROLE]
當指定 AS
子句時,陳述式執行會考慮與指定使用者關聯的任何權限限制,包括由 user
WITH ROLE
指定的所有角色(如果存在)。結果是,陳述式實際授予的權限可能會相對於指定的權限減少。
以下條件適用於 AS
子句user
AS
僅在指定user
具有權限限制時才生效(這表示啟用partial_revokes
系統變數)。如果給定
WITH ROLE
,則必須將指定的所有角色授予給指定的user
。指定的
user
應該是指定為'
、user_name
'@'host_name
'CURRENT_USER
或CURRENT_USER()
的 MySQL 帳戶。目前使用者可以與WITH ROLE
一起指定,以便執行使用者希望GRANT
使用一組可能與目前工作階段內的作用中角色不同的已套用角色執行。AS
不能用於取得執行GRANT
陳述式的使用者所不擁有的權限。執行使用者必須至少擁有要授予的權限,但AS
子句只能限制授予的權限,而不能提升它們。就授予的權限而言,
AS
不能指定比執行GRANT
陳述式的使用者具有更多權限(更少限制)的使用者/角色組合。AS
使用者/角色組合允許比執行使用者具有更多權限,但前提是陳述式未授予這些額外權限。AS
僅支援授予全域權限 (ON *.*
)。不支援針對
PROXY
授予使用AS
。
以下範例說明 AS
子句的效果。建立一個具有一些全域權限以及對這些權限的限制的使用者 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;
現在,使用一個沒有自己權限限制的帳戶,將同一組全域權限授予多個使用者,但每個使用者都具有 AS
子句施加的不同限制,並檢查實際授予哪些權限。
此處的
GRANT
陳述式沒有AS
子句,因此授予的權限與指定的權限完全相同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
陳述式具有AS
子句,因此授予的權限與指定的權限相同,但套用了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`@`%` | +----------------------------------------------------+
如先前所述,
AS
子句只能新增權限限制;它不能提升權限。因此,儘管u1
具有DELETE
權限,但該權限不包含在授予的權限中,因為陳述式未指定授予DELETE
。此處的
GRANT
陳述式的AS
子句會使u1
的角色r1
處於作用中狀態。該角色會取消u1
的一些限制。因此,授予的權限有一些限制,但不如先前GRANT
陳述式的限制多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
陳述式包含 AS
子句,則會忽略執行陳述式的使用者的權限限制(而不是像在沒有 user
AS
子句的情況下一樣套用)。
可選的 WITH
子句用於允許使用者授與其他使用者權限。WITH GRANT OPTION
子句讓使用者能夠將其在指定權限層級擁有的任何權限授予其他使用者。
若要將 GRANT OPTION
權限授予帳戶,但不變更其其他權限,請執行此操作:
GRANT USAGE ON *.* TO 'someuser'@'somehost' WITH GRANT OPTION;
請小心將 GRANT OPTION
權限授予哪些人,因為具有不同權限的兩個使用者可能會合併權限!
您無法授予另一個使用者您自己沒有的權限; GRANT OPTION
權限僅允許您指派您自己擁有的權限。
請注意,當您在特定權限層級授予使用者 GRANT OPTION
權限時,該使用者在該層級擁有的任何權限(或未來可能被授予的權限)也可以由該使用者授予其他使用者。假設您授予使用者在資料庫上的 INSERT
權限。如果您接著授予該使用者在資料庫上的 SELECT
權限,並指定 WITH GRANT OPTION
,則該使用者不僅可以將 SELECT
權限授予其他使用者,也可以授予 INSERT
權限。如果您接著將資料庫上的 UPDATE
權限授予使用者,則該使用者可以授予 INSERT
、SELECT
和 UPDATE
。
對於非管理使用者,您不應該全域或針對 mysql
系統綱要授予 ALTER
權限。如果您這樣做,該使用者可能會嘗試透過重新命名資料表來破壞權限系統!
有關與特定權限相關聯之安全風險的更多資訊,請參閱第 8.2.2 節,「MySQL 提供的權限」。
MySQL 和標準 SQL 版本的 GRANT
之間最大的差異是:
MySQL 將權限與主機名稱和使用者名稱的組合相關聯,而不僅僅是使用者名稱。
標準 SQL 沒有全域或資料庫層級的權限,也不支援 MySQL 支援的所有權限類型。
MySQL 不支援標準 SQL
UNDER
權限。標準 SQL 權限以階層方式組織。如果您移除使用者,則會撤銷該使用者已獲得的所有權限。如果您使用
DROP USER
,這在 MySQL 中也適用。請參閱第 15.7.1.5 節,「DROP USER 語句」。在標準 SQL 中,當您刪除資料表時,該資料表的所有權限都會被撤銷。在標準 SQL 中,當您撤銷權限時,也會撤銷基於該權限授予的所有權限。在 MySQL 中,可以使用
DROP USER
或REVOKE
語句來撤銷權限。在 MySQL 中,可以僅針對資料表的某些欄位擁有
INSERT
權限。在這種情況下,您仍然可以在資料表上執行INSERT
語句,前提是您僅為您擁有INSERT
權限的欄位插入值。如果未啟用嚴格 SQL 模式,則省略的欄位將設定為其隱含預設值。在嚴格模式下,如果任何省略的欄位沒有預設值,則會拒絕該語句。(標準 SQL 要求您擁有所有欄位的INSERT
權限。)有關嚴格 SQL 模式和隱含預設值的資訊,請參閱第 7.1.11 節,「伺服器 SQL 模式」和第 13.6 節,「資料類型預設值」。