111
94

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

dots girlsAdvent Calendar 2015

Day 3

脱!ゆるふわMySQL

Last updated at Posted at 2015-12-02

dots girls Advent Calendar 2015の出だしからしゃしゃってる吉澤です!

何も考えないで現時点で最新のMySQL5.7.9を開発環境にインストールしたところ、今までみたことの無いエラーが出てしまいました。

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ’*.*' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

なんだこれは!と思いググったら、5.7以降でsql_modeの初期設定が変わったとのことでした。

select @@SQL_MODE;
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

以前書いていたソースは、ONLY_FULL_GROUP_BYで引っかかってしまっていました。

ONLY_FULL_GROUP_BYを設定していると

GROUP BYを使っていると、非集約カラムをSELECTで参照できなくなります。
つまりGROUP BY使っている場合はSELECTするものを全部GROUP BYに書け、とのことです。

本来であれば難しい対応はありませんが、エラーは一つだけではありませんでした。
全部直すのはちょっと面倒臭いです。

my.cnfを書き換えて強制突破

アンインストールして入れ直すのでもいいと思いましたが、sql_modeの設定を上書きする方法が一番楽かと思います。
my.cnfの位置はhelpで見ると出てきます。

mysql --help | grep my.cnf
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/mysql/my.cnf /etc/my.cnf ~/.my.cnf

デフォルトのmy.cnfはこんなかんじです。

my.cnf
[mysqld]
user = mysql
port = 3306
datadir = /var/lib/mysql
socket  = /var/lib/mysql/mysql.sock
symbolic-links = 0
character-set-server = utf8
skip-character-set-client-handshake
sql_mode = ""

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

空っぽにするのはやはりよくないので、sql_mode = ""のブランクは本番環境のsql_modeなどに合わせて下さい。
MySQLを再起動するとエラーが起こらなくなると思います。
そもそも本番と開発のバージョンが違うことが良くないので時間がある時にVagrantなどに移して環境を整えましょう。

ゆるふわMySQLとは

いろいろ調べている途中に、こんな記事を見つけました。

ルーク!MySQLではkamipo TRADITIONALを使え!

なるほど、いままではMySQLがゆるふわだったからなんとかなってたんですね。
たしかに、予期せぬ動きしてたこともあったような気がします。
ブログの引用のkamipoさんの提示しているTRADITIONALNO_AUTO_VALUE_ON_ZEROONLY_FULL_GROUP_BYを全部理解したほうがいいと思ったので調べてみました。

TRADITIONALを設定していると

int型の数値オーバーの丸めや、適当なdatetime型が今まで自動で更新されていたところがエラーになるようです。
各フレームワークが便利すぎてなんでもやってくれるこの時代、適当なクエリのバグは選出が大変そうなので、これは設定した方がいいです。

NO_AUTO_VALUE_ON_ZEROを設定していると

値が0でもAUTO_INCREMENTにデータが入る挙動を阻止するそうです。
idに0が入るってことですよね?
これは今までの開発時に見たことがないような気がしますがこういう挙動もあるんですね。

ONLY_FULL_GROUP_BYを設定していると

5.7と互換性が無くなり今回みたいなエラーが出てしまうのを防ぐことができます。

5.7以下でもmy.cnfにsql_modeを設定して、脱ゆるふわクエリを目指しましょう\(^o^)/

dots.女子部では見た目がゆるふわでも、コードはゆるふわしてないそんな向上心の高い部活を目指しています!
一緒にスキルアップしたい女子は下記をチェックしてみて下さい!
Twitter
Facebook

明日はkyrieleisonさんよろしくお願いいたします!

111
94
2

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
111
94

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?