20190522のMySQLに関する記事は5件です。

rails6.0でWARNING"DEPRECATION WARNING: Uniqueness validator will no longer enforce case sensitive comparison in Rails 6.1"が発生する理由

出力するケース

railsのバリデーションuniquenessの"大文字小文字の区別"と、対するDBのユニーク制約の"大文字小文字の区別"に不整合があるときに発生します。

具体例

たとえば、railsで以下の様にmodelを定義していたとします。

class Account < ApplicationRecord
  validates :email, uniqueness: true
end

そして、DBにMysqlを使用していてaccounts.emailutf8mb4_unicode_ciなどのcase insensitiveなcollationを指定していたとします。
この時にも同様のWARNIGが出力されます。

出力する理由

Accountモデルのバリデーションuniquenesscase_sensitiveオプションが未指定なのでデフォルトの挙動case_sensitive = trueになります。

その為、railsでのユニークバリデーションは
「大文字小文字の区別をするユニーク制約」を行います。

一方、DBのcollationはutf8mb4_unicode_ciなので、
「大文字小文字の区別をしないユニーク制約」を行います。

この不整合がMysqlでは様々な問題を起こしていたそうで、
rails6.1では仕様変更を行い、デフォルトの挙動を"DBのcollationに合わせる"にする様です。

なのでこのケースだとrails6.1以降はAccountのユニークバリデーションもDBにあわせて
「大文字小文字の区別をしないユニーク制約」に変更されます。

WARNIGの意味

"このケースだとrails6.1以降は挙動が変わるから、rails6.0以前(現在)の挙動をを維持したい場合は
明示的にcase_sensitive:trueを指定してね"って事っぽいです。

railsでのユニークバリデーションは
「大文字小文字の区別をするユニーク制約」を行います。

一方、DBのcollationはutf8mb4_unicode_ciなので、
「大文字小文字の区別をしないユニーク制約」を行います。

参考

https://blog.kamipo.net/entry/2019/05/15/152652
https://railsguides.jp/active_record_validations.html#uniqueness

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MAMPでMediaWikiを構築する

MacにMediaWikiを使用してローカルのprivate wikiを構築しました。
初心者ゆえSQLの設定にまんまとハマったので備忘録です。
MAMPでmysqlを導入した際に、MySQLWorkbenchの設定も行ったので最後に簡単に併記します。

環境

MacOSX Mojave version 10.14.5
5.7.25 MySQL Community Server (GPL)
MAMP version 5.3
MediaWiki version 1.31.1
MySQLWorkbench version 8.0.16

SQL編

MAMPをダウンロード

https://www.mamp.info/en/downloads/

MAMPを起動し、Start Serversを押す。

mysqlを実行する

参考:MAMP ver 5.2環境下で、ターミナルからMySQLにログインする

ターミナルでbinに移動し、mysqlを起動してパスワード(defalt:root)を打ち込む。

cd /Applications/MAMP/Library/bin
$ ./mysql -u root -p
Enter password: root

# 成功時は以下
mysql>

MySQLでユーザーの作成やパスワードの変更

以下を参考にしながら、ユーザーの作成などを行う。

参考:MySQLインストール時にやること(DBとユーザーの作成等)
参考:【MySQL】ユーザーを作成と権限の追加

mysql
mysql> CREATE USER 'ユーザー名'@localhost IDENTIFIED BY 'パスワード';
mysql> USE mysql;
mysql> select user, host from user;

/*結果はこれ*/
+---------------+-----------+
| user          | host      |
+---------------+-----------+
()
| ユーザー名     | localhost |
()
+---------------+-----------+
7 rows in set (0.00 sec)

トラブルシューティング

rootのパスワードを変更したつもりでもう一度ログインしようとしたところめっちゃエラーが出た。
参考:MySQL の root パスワード忘れた時
参考:MySQLのrootパスワード忘れ時のリセット対応方法

# MySQL を停止
sudo /etc/init.d/mysqld stop
# セーフモードで起動
./mysqld_safe --skip-grant-tables &
# rootでログイン
./mysql -uroot
mysql
use mysql;
/*任意のパスワードを設定*/
update user set authentication_string=PASSWORD('パスワード') where user='root';

flush privileges;
quit
#起動
./mysqld
mysql
/*起動後にステータスの確認*/
/*Current userが目的のものになっているか確認*/

mysql> status

上記がうまくいかなかった場合もあったが、こちらの方法で変更したパスワードでrootにログインできるようになった。
参考:MySQLのrootパスワード忘れ時のリセット対応方法

# init-fileオプションでmysqlを起動
./mysqld --init-file=/path/to/init --user=mysql &

mysql> mySET PASSWORD FOR 'root'@'localhost' = PASSWORD('パスワード');

# ログイン
./mysql -u root -p でパスワードを入れてログイン

MAMPからSQLサーバーが立ち上がらなくなることもあったがこちらで解決。

参考:【MAMP】MySQLが起動しない場合の対処方法2つ


Mediawiki編

Mediawikiを公式からダウンロード
https://www.mediawiki.org/wiki/Download

MAMPのサーバーを起動して、ダウンロードしたフォルダをhtdocsに放り込む。

アプリケーション > MAMP > htdocs > bluespice

http://localhost:8888/bluespice/ にアクセスで簡単につながる。

最初ログインできなかったので以下を参考にした。
参考:Mediawikiを構築したのにセッションのエラーで自分でログインできないとき

LocalSettings.phpをSublime Textなどのコードエディターで開いて、
$wgMainCacheType = CACHE_ANYTHING;に書き換え。

細かい設定などは手順通りに行う。


おまけ:MySQLworkbenchから'ユーザー名'のユーザーにアクセスする。

MySQLworkbenchからwikiのデータベースを覗き見ることができる。
最初は繋がらなかったが、設定のポートの番号を変えたら接続できた。
mysqlにログインしてから、

mysql
mysql> show variables like 'port';

でポート番号を確認してから、MySQLworkbenchの設定のportに反映させた。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQL業務でよく使うコマンド集

業務でほぼ週に1度は使用SQL文を叩いているのでまとめようと思い、メモ代わりに共有できたらなと思います。

データベース管理ソフト

データベースの管理はこれらの管理ソフトを使用するといいかと思います。
MacOSとWindowsで異なるので注意してください。

MacOSの方

Squel Proダウンロードページ

Windowsの方

HeidiSQLのダウンロードページ

コマンド集

カラムの合計値

SUM

SUM関数を使用することで、列の値の合計値を求めることができます。

mysql> SELECT * FROM test_table2;
+------+-------+
| name | score |
+------+-------+
| 太郎 |    80 |
| 次郎 |    70 |
| 三郎 |    92 |
| 四郎 |    88 |
| 五郎 |    76 |
| 太郎 |    75 |
| 次郎 |    98 |
| 三郎 |   100 |
| 四郎 |    80 |
| 五郎 |    60 |
+------+-------+
10 rows in set (0.00 sec)

mysql> SELECT SUM( score ) FROM test_table2;
+--------------+
| SUM( score ) |
+--------------+
|          819 |
+--------------+
1 row in set (0.01 sec)

条件検索の設定

WHERE

SELECT文では指定したテーブル(FROM句)に対して、検索条件(WHERE句)にマッチするレコード(行)の指定フィールド(列)を表示します。SELECTに続くのは列名、と覚えましょう。

mysql> SELECT title, price FROM book_list
    -> WHERE
    -> author = 'auth_A';
+--------+-------+
| title  | price |
+--------+-------+
| book_A |  1500 |
| book_G |   400 |
+--------+-------+

テーブル結合

DBからデータを取り出す際、複数テーブルからデータを検索して取得するといったケースも多々あるかと思います。

内部結合と外部結合

まず、2つのテーブルを結合する方法として、大きく内部結合と外部結合というものが存在しています。

内部結合は、それぞれのテーブルの指定したカラムの値が一致するものだけを結合します。

外部結合は、内部結合のようにそれぞれのテーブルの指定したカラムの値が一致するものを結合するのに加え、どちらかのテーブルにしか存在しないものに関しても取得します。

INNER JOIN(内部結合)

JOINした2つのテーブルを比較し、結合条件に一致した行だけを返すことができます。

mysql> SELECT purchase.id_g, name FROM goods 
    -> INNER JOIN purchase ON purchase.id_g=goods.id_g;
+------+--------------------+
| id_g | name               |
+------+--------------------+
|    1 | 饅頭               |
|    1 | 饅頭               |
|    1 | 饅頭               |
|    2 | みたらし団子         |
|    2 | みたらし団子         |
|    4 | 抹茶団子            |
+------+--------------------+

LEFT JOIN(外部結合)

JOINの左側のテーブルが結合条件に一致しなくてもレコードを返すことができます。

mysql> SELECT purchase.id_g,name FROM goods 
    -> LEFT OUTER JOIN purchase ON purchase.id_g=goods.id_g;
+------+--------------------+
| id_g | name               |
+------+--------------------+
|    1 | 饅頭               |
|    1 | 饅頭               |
|    4 | 抹茶団子           |
|    2 | みたらし団子       |
|    1 | 饅頭               |
|    2 | みたらし団子       |
| NULL | 八つ橋             |
+------+--------------------+

RIGHT JOIN(外部結合)

JOINの右側のテーブルが結合条件に一致しなくてもレコードを返すことができます。

mysql> SELECT purchase.id_g,name FROM goods 
    -> RIGHT JOIN purchase ON purchase.id_g=goods.id_g;
+------+--------------------+
| id_g | name               |
+------+--------------------+
|    1 | 饅頭               |
|    1 | 饅頭               |
|    1 | 饅頭               |
|    2 | みたらし団子       |
|    2 | みたらし団子       |
|    4 | 抹茶団子           |
+------+--------------------+

データ結合

UNION

複数のSELECT文をまとめることが出来ます。

mysql> SELECT 1  AS NUM
    -> UNION
    -> SELECT 2 AS NUM;

+-----+
| NUM |
+-----+
|   1 |
|   2 |
+-----+
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

php-pecl-mysql-xdevapiをインストールするとApacheのリロードに失敗する問題

はじめに

PHPのモジュールで、php-pecl-mysql-xdevapiをインストールしてから
Apacheが決まった時間帯に勝手に落ちる現象が発生していたので
その原因と対策について投稿してみます。

環境

CentOS Linux release 7.6.1810 (Core)
Server version: Apache/2.4.6 (CentOS)
PHP 7.3.5 (cli)

決まった時間に落ちるのでcronを確認

/var/log/cron をみてみる。

run-parts(/etc/cron.daily)[21871]: starting logrotate
run-parts(/etc/cron.daily)[21891]: finished logrotate

cron.dailyでlogrotateが動いている。

/var/log/httpd/配下のログを確認すると、Apacheが落ちるタイミングで
ログがローテートされている。

ログローテート設定の確認

/var/logrotate.d/httpd の中身を確認してみると

/var/log/httpd/*log {
    missingok
    notifempty
    sharedscripts
    compress
    delaycompress
    postrotate
    create 0644
        /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
    endscript
}

ログローテートの際に、systemctl reload httpd が実行されている。
リロードの際にApacheが落ちてる模様

Apacheのログを確認

落ちた時間付近の /var/log/httpd/error_log に気になるログが...

PHP Fatal error:  Class mysql_xdevapi\\XSession cannot extend from interface CURLMOPT_MAXCONNECTS in Unknown on line 0
[core:notice] [pid 17512] AH00060: seg fault or similar nasty error detected in the parent process

php-pecl-mysql-xdevapiが原因っぽいログがでてる。
どうやらこのモジュールが原因でリロードした際にApacheが起動してこない模様

Apacheをリロードしてみる

systemctl reload httpd

やはりApacheが起動してこない...
ログをみると先ほど出ていたログと同様のログがでてる。

php-pecl-mysql-xdevapiを削除してみる

yum remove php-pecl-mysql-xdevapi

削除!

再度Apacheをリロードしてみる

systemctl restart httpd

一回リスタートかけてリロード実施!

systemctl reload httpd

Apacheが落ちてない!

php-pecl-mysql-xdevapiをインストールした状態でApacheをリロードすると
Apacheが立ち上がらなくなる模様

対策

1.そもそもphp-pecl-mysql-xdevapiを使用しない

2.restartなら問題なく起動するので
 /etc/logrotate.d/httpd のreload部分をrestartに変更することで
 問題なく起動する。
 ただし、ログローテートの度にApacheのリスタートが実施される。

3.ローテートの設定を下記のように、postrotateとendscriptの間を
 copytruncateに変更するとリロードなくログローテートが行える。

/var/log/httpd/*log {
    missingok
    notifempty
    sharedscripts
    compress
    delaycompress
    postrotate
    copytruncate
    endscript
}

copytruncateはリロードなくログローテートできるが、ローテート最中にきた
アクセスについては記録できないとのこと

おわりに

エンジニアになり1年たったので、たまにはこうやって記事書いたりしていこうと
思います。(たぶん)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue. Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.

git clone して来てbundle
しようとしても、

Fetching mysql2 0.5.2
Installing mysql2 0.5.2 with native extensions

でつまずいて進まない、、、

ボクの場合の解決方法

rubyのバージョンを-v 2.5.3に変更してGemfile.lockを削除

$ rbenv local 2.5.3
$ sudo rm -rf Gemfile.lock

解決コマンド

$ brew install openssl
$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include"
$ bundle install

参考サイト

https://qiita.com/Yutazon/items/8d1e538b8c89fc7bda3c

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む