今日はなにの日。

気になったこと勉強になったことのメモ。

今日は、2022年で知ったMySQLの7つのことについての日。

初めに

この記事はMySQL Advent Calendar 2022の19日目の記事です。

本記事では、今年一年を通してMySQLに触れててへぇーってなった7つのことについてまとめてます。

目次

2022年で知ったMySQLの7つのこと

実務を通して知ったものもあれば、書籍を読んでいて知ったものなど様々あります。

順番は特に関係ないです。

  1. 特定のデータベースにあるテーブル一覧を見る方法
  2. テーブルをSELECTする方法
  3. 権限はスキーマが消えても残る
  4. バージョンが消える
  5. GRANTって複数テーブル指定できない
  6. SETの権限
  7. Event Scheduler

特定のデータベースにあるテーブル一覧を見る方法

今まで、特定のデータベースにあるテーブル一覧は、以下の方法で見てました。

  1. データベースを選択

    1. use database
      
  2. テーブル一覧表示

    1. show tables;
      
(root@localhost) [test] 8.0.31 > use advent;
Database changed

(root@localhost) [advent] 8.0.31 > show tables;
+------------------+
| Tables_in_advent |
+------------------+
| test1            |
| test2            |
+------------------+
2 rows in set (0.00 sec)

これが一行でできるらしい。

 SHOW TABLES FROM database;

↓実行結果

(root@localhost) [advent] 8.0.31 > SHOW TABLES FROM advent;
+------------------+
| Tables_in_advent |
+------------------+
| test1            |
| test2            |
+------------------+
2 rows in set (0.01 sec)

その都度データベースを切り替える必要性がないので便利だなと思いました。

テーブルをSELECTする方法

テーブルのデータ内容を見たいとき以下の様にSELECTすると思います。

(root@localhost) [advent] 8.0.31 > select * from test1;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

これを更に短縮できるやり方があるらしい。

TABLE は、MySQL 8.0.19 で導入された DML ステートメントで、指定されたテーブルの行とカラムを返します。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.2.12 TABLE ステートメント

TABLE table;

↓実行結果

(root@localhost) [advent] 8.0.31 > TABLE test1;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

ちなみに、order by も使えます。

(root@localhost) [advent] 8.0.31 > TABLE test1 order by i limit 1;
+------+
| i    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

軽くテーブルの中身を見るだけならこっちのほうが便利だなと思いました。

権限はスキーマが消えても残る

MySQL では、データベースまたはテーブルを削除しても、どの権限も自動的には取り消されません。 ただし、ルーチンを削除した場合は、そのルーチンに付与されたルーチンレベルの権限がすべて取り消されます。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.7.1.6 GRANT ステートメント

すでにtest1テーブルに権限を付与したユーザが存在しています。

このtest1テーブルを削除しても権限は残り続けます。

(newuser@localhost) [(none)] 8.0.31 > show grants for newuser@localhost;
+-----------------------------------------------------------+
| Grants for newuser@localhost                              |
+-----------------------------------------------------------+
| GRANT SUPER ON *.* TO `newuser`@`localhost`               |
| GRANT SELECT ON `advent`.`test1` TO `newuser`@`localhost` |
| GRANT SELECT ON `advent`.`test2` TO `newuser`@`localhost` |
+-----------------------------------------------------------+
3 rows in set (0.00 sec)

test1を削除してみる。

(root@localhost) [advent] 8.0.31 > drop table test1;
Query OK, 0 rows affected (0.03 sec)

(root@localhost) [advent] 8.0.31 > TABLE test1;
ERROR 1146 (42S02): Table 'advent.test1' doesn't exist

(root@localhost) [advent] 8.0.31 > show grants for newuser@localhost;
+-----------------------------------------------------------+
| Grants for newuser@localhost                              |
+-----------------------------------------------------------+
| GRANT SUPER ON *.* TO `newuser`@`localhost`               |
| GRANT SELECT ON `advent`.`test1` TO `newuser`@`localhost` |
| GRANT SELECT ON `advent`.`test2` TO `newuser`@`localhost` |
+-----------------------------------------------------------+
3 rows in set (0.00 sec)

テーブルはなくなっても、権限は残ってます。

てっきり消えると思ってました。

バージョンが消える

MySQL 8.0.29 がダウンロードできなくなりました。

詳細は↓を見ていただくとわかりやすいと思います。

MySQL Server8.0.29では何が起きたのか?(リリースノートを眺める) - 41から始めました

そんなこともあるんだーって思いました。

ついでに、AWSのRDSでも非対応のバージョンになりました。

現在(2022年12月18日)RDSで対応しているのは以下のバージョンです。

  • 8.0.30
  • 8.0.28
  • 8.0.27
  • 8.0.26
  • 8.0.25
  • 8.0.23

Amazon RDS での MySQL のバージョン - Amazon Relational Database Service

GRANTって複数のスキーマを指定できない

権限によっては、データベースやテーブル単位で設定が可能です。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.7.1.6 GRANT ステートメント

例えば、AというテーブルにはSELECTの権限のみをつけ、BというテーブルにはSELECT,INSERT,UPDATE,DELETEをつけるみたいな。

ですが、AというテーブルとBというテーブルにそれぞれ別でGRANT文を実行する必要があります。

(root@localhost) [advent] 8.0.31 > show grants for newuser@localhost;
+---------------------------------------------+
| Grants for newuser@localhost                |
+---------------------------------------------+
| GRANT USAGE ON *.* TO `newuser`@`localhost` |
+---------------------------------------------+
1 row in set (0.00 sec)

newuser ユーザーにtest1test2のSELECT権限を追加するには2つのGRANT文を実行します。

GRANT SELECT on advent.test1 to newuser@localhost;
GRANT SELECT on advent.test2 to newuser@localhost;

↓実行結果

(root@localhost) [advent] 8.0.31 > show grants for newuser@localhost;
+-----------------------------------------------------------+
| Grants for newuser@localhost                              |
+-----------------------------------------------------------+
| GRANT USAGE ON *.* TO `newuser`@`localhost`               |
| GRANT SELECT ON `advent`.`test1` TO `newuser`@`localhost` |
| GRANT SELECT ON `advent`.`test2` TO `newuser`@`localhost` |
+-----------------------------------------------------------+
3 rows in set (0.00 sec)

一度につけれないの不便だなと思いました。

SETの権限

SET SESSIONだと権限はいらないが、GLOBALだとSUPER権限が必要になる。

SUPER

CHANGE REPLICATION SOURCE TO, CHANGE MASTER TO, KILL, PURGE BINARY LOGS, SET GLOBALmysqladmin debug コマンドなどの他の管理操作の使用を有効にします。 レベル: グローバル。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.7.1.6 GRANT ステートメント

SUPERなし

(newuser@localhost) [(none)] 8.0.31 > show grants for newuser@localhost
    -> ;
+-----------------------------------------------------------+
| Grants for newuser@localhost                              |
+-----------------------------------------------------------+
| GRANT USAGE ON *.* TO `newuser`@`localhost`               |
| GRANT SELECT ON `advent`.`test1` TO `newuser`@`localhost` |
| GRANT SELECT ON `advent`.`test2` TO `newuser`@`localhost` |
+-----------------------------------------------------------+
3 rows in set (0.00 sec)

(newuser@localhost) [(none)] 8.0.31 > set autocommit = 1;
Query OK, 0 rows affected (0.00 sec)

(newuser@localhost) [(none)] 8.0.31 > set global autocommit = 1;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation

SUPERあり

(newuser@localhost) [(none)] 8.0.31 > show grants for newuser@localhost;
+-----------------------------------------------------------+
| Grants for newuser@localhost                              |
+-----------------------------------------------------------+
| GRANT SUPER ON *.* TO `newuser`@`localhost`               |
| GRANT SELECT ON `advent`.`test1` TO `newuser`@`localhost` |
| GRANT SELECT ON `advent`.`test2` TO `newuser`@`localhost` |
+-----------------------------------------------------------+
3 rows in set (0.00 sec)

(newuser@localhost) [(none)] 8.0.31 > set autocommit = 1;
Query OK, 0 rows affected (0.00 sec)

(newuser@localhost) [(none)] 8.0.31 > set global autocommit = 1;
Query OK, 0 rows affected (0.00 sec)

Event Scheduler

MySQLにもスケジュールでSQLを実行できるEvent Schedulerなるものが存在する。

MySQL イベントは、スケジュールに従って実行されるタスクです。そのため、スケジュールされたイベントと呼ばれることがあり ます。イベントを作成すると、特定の日時に開始および終了する 1 つ以上の定期的な間隔で実行される 1 つ以上の SQL ステートメントを含む名前付きデータベース オブジェクトが作成されます。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 25.4.1 イベントスケジューラの概要

詳細は別記事にまとめてますのでこちらをご覧下さい。

今日は、MySQLにEvent Scheduler なるものがあるらしいので使ってみたの日。 - 今日はなにの日。

深夜バッチとかで利用するみたいです。

いかがでしたでしょうか。

私は、MySQLに触れ続けてもう4,5年経ちますが、まだまだ知らないことばかりですね。