0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【MySQL】SQLモードとは何か?デフォルトで有効なモードの内容を確認する

0
Posted at

はじめに

こんにちは。
MySQLには、SQLモードと呼ばれる設定があります。
この記事では、MySQLのSQLモードの概要と、デフォルトで有効な6つのモードの意味を整理します。

実行環境

  • MySQL 8.0.46

SQLモードとは

SQLモードは、MySQLの構文チェックやデータ検証の挙動を制御する設定です。

たとえば、不正な日付や範囲外の値をINSERTしようとしたとき、エラーにするか警告だけで通すかをSQLモードで制御できます。

現在のSQLモードを確認する

現在のSQLモードは次のクエリで確認できます。

SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;

デフォルトでは、次の6つが有効になっています。

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

デフォルトで有効な6つのモード

ONLY_FULL_GROUP_BY

GROUP BYに含まれないカラムをSELECTに書くことを制限します。

SELECT name, city FROM users GROUP BY city;

ONLY_FULL_GROUP_BY が有効な場合、name がGROUP BYに含まれていないためこのクエリはエラーになります。

STRICT_TRANS_TABLES

不正な値の INSERT や UPDATE を警告ではなくエラーにします。

CREATE TABLE items (
  name VARCHAR(5) NOT NULL
);

INSERT INTO items (name) VALUES ('abcdefgh');

STRICT_TRANS_TABLES が有効な場合、このクエリのように5文字を超える値をnameに登録しようとするとエラーになります。
無効の場合、値が 'abcde' に切り詰められ、警告だけで INSERT が成功します。

NO_ZERO_IN_DATE

月や日が 0 の日付(例: '2024-00-15')を不正とみなします。
STRICT_TRANS_TABLES が有効の場合エラーになります。

NO_ZERO_DATE

'0000-00-00' を不正な日付とみなします。
こちらも STRICT_TRANS_TABLES が有効の場合エラーになります。

ERROR_FOR_DIVISION_BY_ZERO

0除算が発生した場合の扱いを制御します。

SELECT 1 / 0;

STRICT_TRANS_TABLES と組み合わせると、INSERT や UPDATE の中で0除算が起きた場合にエラーになります。
無効の場合は NULL が返り、警告だけが出ます。

NO_ENGINE_SUBSTITUTION

CREATE TABLE で指定したストレージエンジンが使えない場合にエラーにします。
無効の場合は、指定したエンジンの代わりにデフォルトエンジンが自動で使われます。

SQLモードの変更方法

セッション単位で変更する

現在の接続だけに適用したい場合は SET SESSION を使います。

SET SESSION sql_mode = CONCAT(@@SESSION.sql_mode, ',NO_AUTO_VALUE_ON_ZERO');

グローバルで変更する

新しい接続に適用したい場合は SET GLOBAL を使います。

SET GLOBAL sql_mode = CONCAT(@@GLOBAL.sql_mode, ',NO_AUTO_VALUE_ON_ZERO');

SET GLOBAL を変更しても、すでに接続しているセッションには影響せず、変更後に新しく接続したセッションから反映されます。

永続化する

SET GLOBAL は、MySQLを再起動すると元に戻ります。
永続的に設定を変えたい場合は、my.cnfmy.ini といった設定ファイルに記述します。

[mysqld]
sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO

MySQL 8.0以降では SET PERSIST を使うこともできます。

SET PERSIST sql_mode = CONCAT(@@GLOBAL.sql_mode, ',NO_AUTO_VALUE_ON_ZERO');

SET PERSIST は設定ファイルを直接編集しなくても、再起動後に設定が残ります。

まとめ

  • SQLモードはMySQLの構文チェックやデータ検証の厳しさを制御する設定
  • MySQL 8.0のデフォルトでは6つのモードが有効である

お読みいただきありがとうございました。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?