🧑‍🎓

MySQLのGRANT文を理解する

2025/01/12に公開

今までGRANT文を使う機会がありませんでしたが、最近使うことが増えてきたので基本的な使い方をまとめてみます。

そもそもGRANT文とは

GRANT文はDatabaseに対する読み取りなどの権限を特定のDBユーザーに付与することができるクエリです。
逆に権限を剥奪するのはREVOKE文で行います。

ちなみに、grantとrevokeの英単語には
grant:〔権利などを〕許諾する、供与する、与える
revoke:〔~を〕無効にする、〔~を〕取り消す
などの意味があります。

基本構文

GRANT

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 ] ...
        ]
    ]

object_type: {
    TABLE
  | FUNCTION
  | PROCEDURE
}

priv_level: {
    *
  | *.*
  | db_name.*
  | db_name.tbl_name
  | tbl_name
  | db_name.routine_name
}

user_or_role: {
    user
  | role
}

引用:https://dev.mysql.com/doc/refman/8.4/en/grant.html

※引用先より一部構文のみを抜粋しています。
※WITH GRANT OPTIONを付けることで、その権限を付与されたユーザーが他のユーザーにもその権限を付与することが出来るようになります。
※roleはMySQL8系で追加された、複数の権限を名前付きコレクションとして管理できるようになる機能です。AS user〜の部分もrole関連です。これらは本記事では扱いません。

REVOKE

REVOKE [IF EXISTS]
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type] priv_level
    FROM user_or_role [, user_or_role] ...
    [IGNORE UNKNOWN USER]

REVOKE [IF EXISTS] ALL [PRIVILEGES], GRANT OPTION
    FROM user_or_role [, user_or_role] ...
    [IGNORE UNKNOWN USER]

REVOKE [IF EXISTS] PROXY ON user_or_role
    FROM user_or_role [, user_or_role] ...
    [IGNORE UNKNOWN USER]

REVOKE [IF EXISTS] role [, role ] ...
    FROM user_or_role [, user_or_role ] ...
    [IGNORE UNKNOWN USER]

user_or_role: {
    user (see Section 8.2.4, “Specifying Account Names”)
  | role (see Section 8.2.5, “Specifying Role Names”
}

引用:https://dev.mysql.com/doc/refman/8.4/en/revoke.html

※引用先より一部構文のみを抜粋しています。
※IGNORE UNKNOWN USERオプションを付けて実行すると、もし指定したユーザーが存在しなくてもエラーが出なくなるようです。

実際に使ってみる

GRANT

# mysql -u root -p
mysql> CREATE USER ‘test_user’@‘%’ IDENTIFIED BY ‘password’;	# テスト用ユーザー作成

テスト用ユーザーを作ります。
デフォルトでは元から作られているperformance_schemaやperformance_schemaスキーマに対する権限以外には特に何の権限も持ちません。

mysql> SELECT User FROM mysql.user;	# ユーザー一覧
+------------------+
| User             |
+------------------+
| root             |
| test_user        |
| healthchecker    |
| mysql.infoschema |
| mysql.session    |
| mysql.sys        |
| root             |
+------------------+
7 rows in set (0.00 sec)

mysql> CREATE DATABASE privilege_test;	# テスト用スキーマ作成
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| privilege_test     |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

mysql> exit
# mysql -u test_user -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.00 sec)

ここでtest_userは権限が一切与えていないprivilege_testスキーマの情報を閲覧できないことが分かります。

mysql> exit
# mysql -u root -p
mysql> GRANT SELECT ON privilege_test.* TO 'test_user'@'%';	# test_userユーザーにprivilege_testスキーマに対するSELECT権限を付与

ようやく満を持して本記事主役のGRANT文くん登場。
指定できる他のpriv_type(SELECTの部分)一覧はこちら

privilege_test.の部分でテーブル名を指定します。*はワイルドカード指定です。

'test_user'@'%'の%の部分はユーザーの接続ホスト先を指定します。*はワイルドカード指定です。
そのホストからの接続でのみ、付与した権限での操作が可能になります。
この部分はシングルクォートや@を使わずに指定することもできますが、その場合は'test_user'@'localhost'を指定したのと同義になります。

# mysql -u test_user -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
| privilege_test     |
+--------------------+
3 rows in set (0.00 sec)

mysql> use privilege_test
Database changed

閲覧権限を付与したのでtest_userでprivilege_testが閲覧できるようになり、switchまで出来るようになっています。

REVOKE

mysql> exit
# mysql -u root -p
mysql> REVOKE SELECT ON privilege_test.* FROM 'test_user'@'%';	# test_userに付与したprivilege_testスキーマに対するSELECT権限を剥奪

REVOKE文はGRANT文とほぼ同じような構文です。
TOがFROMに変わるくらいです。

mysql> exit
# mysql -u test_user -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.00 sec)

権限が剥奪されたので、privilege_testスキーマがtest_userから見れなくなっています。

以上、簡単ではありましたがGRANT文とREVOKE文の挙動を学ぶことができました。

Discussion