MySQL 8.0 リファレンスマニュアル


4.5.1.6 mysql クライアントのヒント

このセクションでは、mysql のより効果的な使用方法および mysql の操作動作について説明します。

入力行の編集

mysql は入力行の編集をサポートし、現在の入力行を修正したり以前の入力行を呼び出したりできます。 たとえば、left-arrow キーと right-arrow キーは現在の入力行内で水平に移動し、up-arrow キーと down-arrow キーは以前に入力した行のセット内で上下に移動します。 「バックスペース」でカーソルの前の文字を削除でき、新しい文字を入力するとカーソルの位置に挿入されます。 行を入力するには、「Enter」を押します。

Windows では、編集キーシーケンスはコンソールウィンドウでコマンドの編集に関してサポートされているものと同じです。 Unix では、キーシーケンスは mysql のビルドに使用された入力ライブラリ (たとえば、libedit または readline ライブラリ) に依存します。

libedit ライブラリおよび readline ライブラリのドキュメントは、オンラインで入手できます。 所定の入力ライブラリで許可されるキーシーケンスのセットを変更するには、ライブラリ起動ファイルでキーバインドを定義します。 これはホームディレクトリにあるファイルで、.editrclibedit 用、.inputrcreadline 用です。

たとえば libedit では、Control+W は現在のカーソル位置の前にあるものをすべて削除し、Control+U は行全体を削除します。 readline では、Control+W はカーソルの前の単語を削除し、Control+U は現在のカーソル位置の前にあるものをすべて削除します。 mysqllibedit を使用してビルドされた場合は、これら 2 つのキーに関して readline の動作を好むユーザーは、.editrc ファイルに次の行を置くことができます (必要に応じてファイルを作成します)。

bind "^W" ed-delete-prev-word
bind "^U" vi-kill-line-prev

現在のキーバインディングのセットを表示するには、.editrc の最後に bind のみを示す行を一時的に配置します。mysql では、起動時にバインディングが表示されます。

インタラクティブ履歴の無効化

up-arrow キーを使用すると、現在および前のセッションから入力行をリコールできます。 コンソールが共有されている場合、この動作は適切でない可能性があります。mysql では、ホストプラットフォームに応じて、対話型履歴の一部または全部の無効化をサポートしています。

Windows では、履歴はメモリに保存されます。 Alt+F7 は、現在の履歴バッファのメモリーに格納されている入力行をすべて削除します。 また、F7 で表示され、F9 でリコールされた入力行の前の連番のリストも削除されます。 Alt+F7 で現在の履歴バッファを再移入した後に入力された新しい入力行。 --syslog オプションを使用して mysql を起動した場合、バッファをクリアしても Windows イベントビューアへのロギングは妨げられません。 コンソールウィンドウを閉じると、現在の履歴バッファもクリアされます。

Unix で対話型履歴を無効にするには、まず .mysql_history ファイルが存在する場合はそれを削除します (それ以外の場合は以前のエントリがリコールされます)。 次に、--histignore="*"オプションを指定して mysql を起動し、すべての新しい入力行を無視します。 リコール (およびロギング) 動作を再度有効にするには、オプションを指定せずに mysql を再起動します。

.mysql_history ファイルが作成されないようにし (履歴ファイルの制御 を参照)、--histignore="*"を使用して mysql クライアントを起動すると、対話型履歴リコール機能が完全に無効になります。 または、--histignore オプションを省略すると、現在のセッション中に入力された入力行をリコールできます。

Windows における Unicode のサポート

Windows には、コンソールからの読取りおよびコンソールへの書込み用に UTF-16LE に基づく API が用意されています。Windows 用の mysql クライアントでは、これらの API を使用できます。 Windows インストーラによって、MySQL メニューに MySQL command line client - Unicode という名前の項目が作成されます。 この項目は、Unicode を使用して MySQL サーバーにコンソール経由で通信するように設定されたプロパティーで mysql クライアントを呼び出します。

このサポートを手動で利用するためには、互換性のある Unicode フォントを使用するコンソール内で mysql を実行し、デフォルト文字セットをサーバーとの通信でサポートされる Unicode 文字セットに設定します。

  1. コンソールウィンドウを開きます。

  2. コンソールウィンドウプロパティーに移動して「フォント」タブを選択し、Lucida Console またはその他の互換性のある Unicode フォントを選択します。 コンソールウィンドウはデフォルトでは Unicode に不適切な DOS ラスターフォントを使用するため、これが必要です。

  3. mysql.exe--default-character-set=utf8 (または utf8mb4) オプションで実行します。 utf16le はクライアント文字セットとして使用できない文字セットの 1 つであるため、このオプションが必要です。 許可されていないクライアント文字セットを参照してください。

これらの変更により、mysql は Windows API を使用して UTF-16LE を使用してコンソールと通信し、UTF-8 を使用してサーバーと通信します。 (前述のメニュー項目は、フォントと文字セットを今説明したように設定します。)

mysql を起動するたびにこれらのステップを実行しなくてもいいように、mysql.exe を呼び出すショートカットを作成できます。 このショートカットは、コンソールフォントを Lucida Console またはその他の互換性のある Unicode フォントに設定し、--default-character-set=utf8 (または utf8mb4) オプションを mysql.exe に渡すようにしてください。

または、コンソールフォントの設定のみを行うショートカットを作成し、文字セットは my.ini ファイルの [mysql] グループで設定します。

[mysql]
default-character-set=utf8
クエリー結果を縦に表示する

クエリー結果の中には、縦表示の方が、通常の横向きの表形式よりもはるかに読みやすい場合があります。 セミコロンの代わりに \G でクエリーを終了することで、クエリーを縦に表示できます。 たとえば、多くの場合、改行を含む長いテキスト値は縦の出力の方がはるかに読みやすくなります。

mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 LIMIT 300,1\G
*************************** 1. row ***************************
  msg_nro: 3068
     date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Jones
    reply: jones@example.com
  mail_to: "John Smith" <smith@example.com>
      sbj: UTF-8
      txt: >>>>> "John" == John Smith writes:

John> Hi.  I think this is a good idea.  Is anyone familiar
John> with UTF-8 or Unicode? Otherwise, I'll put this on my
John> TODO list and see what happens.

Yes, please do that.

Regards,
Jones
     file: inbox-jani-1
     hash: 190402944
1 row in set (0.09 sec)
セーフ更新モードの使用 (--safe-updates)

初心者にとって、使いやすい起動オプションは --safe-updates (または同じ効果のある --i-am-a-dummy) です。 Safe-updates モードは、UPDATE または DELETE ステートメントを発行したが、変更する行を示す WHERE 句を忘れた場合に役立ちます。 通常、このようなステートメントはテーブル内のすべての行を更新または削除します。 --safe-updates では、行を識別するキー値または LIMIT 句 (あるいはその両方) を指定することによってのみ、行を変更できます。 これにより、事故を予防します。 Safe-updates モードでは、非常に大きな結果セットを生成する (または生成すると見積もられる) SELECT ステートメントも制限されます。

--safe-updates オプションを使用すると、mysql は MySQL サーバーに接続するときに次のステートメントを実行して、sql_safe_updatessql_select_limit および max_join_size システム変数のセッション値を設定します:

SET sql_safe_updates=1, sql_select_limit=1000, max_join_size=1000000;

SET ステートメントは、次のようにステートメントの処理に影響します:

  • sql_safe_updates を有効にすると、WHERE 句でキー制約が指定されていない場合、または LIMIT 句 (あるいはその両方) が指定されていない場合に、UPDATE ステートメントと DELETE ステートメントでエラーが発生します。 例:

    UPDATE tbl_name SET not_key_column=val WHERE key_column=val;
    
    UPDATE tbl_name SET not_key_column=val LIMIT 1;
  • sql_select_limit を 1,000 に設定すると、ステートメントに LIMIT 句が含まれていないかぎり、すべての SELECT 結果セットが 1,000 行に制限されます。

  • max_join_size を 1,000,000 に設定すると、サーバーが 1,000,000 を超える行の組合せを調べる必要があると見積もった場合に、複数テーブルの SELECT ステートメントでエラーが発生します。

1,000 および 1,000,000 以外の結果セット制限を指定するには、mysql の起動時に --select-limit および --max-join-size オプションを使用してデフォルトをオーバーライドします:

mysql --safe-updates --select-limit=500 --max-join-size=10000

オプティマイザがキーカラムでインデックスを使用しないことを決定した場合、UPDATE および DELETE ステートメントでは、WHERE 句で指定されたキーを使用してもセーフ更新モードでエラーが発生する可能性があります:

  • メモリー使用量が range_optimizer_max_mem_size システム変数で許可されているメモリー使用量を超える場合、インデックスに対する範囲アクセスは使用できません。 その後、オプティマイザはテーブルスキャンにフォールバックします。 範囲最適化のためのメモリー使用の制限を参照してください。

  • キー比較で型変換が必要な場合は、インデックスを使用できません (セクション8.3.1「MySQL のインデックスの使用の仕組み」 を参照)。 インデックス付けされた文字列カラム c1 が、WHERE c1 = 2222 を使用して数値と比較されるとします。 このような比較では、文字列値が数値に変換され、オペランドが数値的に比較され (セクション12.3「式評価での型変換」 を参照)、インデックスの使用が妨げられます。 safe-updates モードが有効な場合は、エラーが発生します。

MySQL 8.0.13 の時点では、セーフ更新モードには次の動作も含まれます:

  • UPDATE および DELETE ステートメントを使用した EXPLAIN では、セーフ更新エラーは生成されません。 これにより、EXPLAINSHOW WARNINGS を使用してインデックスが使用されない理由を確認できます。これは、range_optimizer_max_mem_size 違反や型変換が発生し、WHERE 句でキーカラムが指定されていてもオプティマイザがインデックスを使用しない場合などに役立ちます。

  • safe-updates エラーが発生すると、エラーメッセージには、失敗の理由に関する情報を提供するために生成された最初の診断が含まれます。 たとえば、range_optimizer_max_mem_size 値を超えたか、型変換が発生したことを示すメッセージが表示される場合があり、そのいずれの場合もインデックスを使用できません。

  • 複数テーブルの削除および更新の場合、いずれかのターゲットテーブルでテーブルスキャンが使用されている場合にのみ、安全な更新を有効にしてエラーが生成されます。

mysql の自動再接続を無効にする

ステートメントの送信中にサーバーとの接続が切断された場合、mysql クライアントはただちに自動的にサーバーに一度再接続してステートメントを再度送信しようとします。 ただし、mysql が再接続に成功しても、最初の接続は終了し、前セッションのオブジェクトと設定は失われます。この中には、一時テーブル、自動コミットモード、およびユーザー定義変数やセッション変数が含まれます。 また、現トランザクションはロールバックします。 この動作は危険な場合があります。たとえば、次の例では、サーバーはユーザーの了解なしに、最初のステートメントと 2 番目のステートメントの間にシャットダウンして再起動させられています。

mysql> SET @a=1;
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO t VALUES(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: test

Query OK, 1 row affected (1.30 sec)

mysql> SELECT * FROM t;
+------+
| a    |
+------+
| NULL |
+------+
1 row in set (0.05 sec)

@a ユーザー変数は接続とともに失われ、再接続後は未定義です。 接続が失われた際に、mysql がエラーで終了することが望ましい場合、mysql クライアントを --skip-reconnect オプションで起動できます。

自動再接続および再接続時の状態情報への影響の詳細は、Automatic Reconnection Controlを参照してください。

mysql クライアントパーサーとサーバーパーサー

mysql クライアントは、サーバー側の mysqld サーバーで使用される完全なパーサーと重複しないパーサーをクライアント側で使用します。 これにより、特定の構成の処理に違いが生じる場合があります。 例:

  • サーバーパーサーは、ANSI_QUOTES SQL モードが有効な場合、"文字で区切られた文字列をプレーン文字列ではなく識別子として扱います。

    mysql クライアントパーサーでは、ANSI_QUOTES SQL モードは考慮されません。 ANSI_QUOTES が有効かどうかに関係なく、"'および`文字で区切られた文字列は同じように扱われます。

  • /*! ... */および/*+ ... */コメント内で、mysql クライアントパーサーは短い形式の mysql コマンドを解釈します。 これらのコマンドはサーバー側で意味を持たないため、サーバーパーサーはこれらを解釈しません。

    mysql でコメント内のショートフォームコマンドを解釈しないことが望ましい場合、部分的な回避策は --binary-mode オプションを使用することです。これにより、\C および\d を除くすべての mysql コマンドが非対話モードで無効になります (mysql にパイプされた入力または source コマンドを使用してロードされた入力の場合)。


関連キーワード:  サーバー, 接続, ステートメント, キー, プログラム, テーブル, 表示, セット, 起動, updates