20210122のMySQLに関する記事は7件です。

PHPでログイン機能

前回の続きです。
PHPカレンダー:https://qiita.com/x49_n/items/64a04a85b72c6d581421

ログイン機能作成

前回作成したカレンダーにログイン機能を追加していきます。

ご参考に:https://www.youtube.com/watch?v=uCvPMe5wsNk

ログイン機能

・新規登録(ユーザー登録)
・ログイン+ログイン確認画面
・ログアウト+ログアウト確認画面

ER図

ER図.png

簡単ですが、ER図を作成しました。(本当はツールを使って作成したかった、、、)
ER図動画化したものについてはTwitterにて公開しています。
https://twitter.com/x49_n/status/1352600436616830976

次回は予定入力欄を作成します!

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

コンテナでDBを作る【mysql】

悩んだ末に絞り出したコンテナ設定の備忘録です。

条件

下記の設定が記載されたテンプレートを元に必要な機能を追記する
・mysql5.7公式dockerイメージを元に、その他必要な設定をcomposeファイルで行う
・データ用のボリュームを用意しコンテナ起動時にマウント
・Mysqlの環境変数の設定がなければDB名等をダミーで作成するシェルが、コンテナ起動時にDBのボリュームが存在しない場合に実行される

これに加え
・初回コンテナ起動時にテーブル定義〜ダミーデータのインポートまで自動で行えるようにしたい

辿り着いた設定

実際のファイルはここに載せると長くなる為載せないけど、こんなイメージのものを作成

composeファイルでイメージがビルド

下記のディレクトリがマウント
・データ用ディレクトリ
・mysql設定ファイル配置ディレクトリ
・エントリーポイント用ディレクトリ

エントリーポイント用ディレクトリに下記を配置
・init.sh(テンプレート)
・テーブル定義用sqlファイル
・データインポート用シェル(インポートするデータサイズが大きい為シェル内で圧縮されたファイルの解凍等も行っている)

テーブル定義とデータ部分のインポートを分けたので何かエラーがあったときに箇所が明確になる
また、テーブル定義かデータのどちらかを差し替えたい場合も分けて対応できる
あと、データインポート用シェルには必要な処理を色々追記できるというメリットがある
(インポートが終わったらdumpファイルを削除するとか)

若干はまったこと

composeファイルに記載した下記の変数について

MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'

この設定によりcomposeファイルで

    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      DB_NAME: test
      DB_USER: root

上記のように設定すると、testDBのrootユーザーにはパスワードが存在しないはずなのに、なぜかパスワードが生成された状態でDBが起動する為不思議に思っていたけど、テンプレートのシェルをよく見たら「パスワードが空または定義されていない場合、これを代入」的な処理になっていたので、これが原因とわかった。

dbName="${DB_NAME:-aaa}"
dbUser="${DB_USER:-bbb}"
dbPassword="${DB_PASSWORD:-ccc}"

sql="create database if not exists ${dbName}"
echo "${sql}" | ${cmd} mysql

sql="grant all on ${dbName}.* to ${dbUser}@'%' identified by '${dbPassword}'"
echo "${sql}" | ${cmd} mysql

細かく検証していないけど、デフォルト(localhostからのアクセスのみ受け付ける)rootユーザーのパスワードが無くなるという設定のための専用変数ということはさすがにないはず。

どこかで配布されているテンプレートなんだろうか、、出どころ不明だけど、今回はこれを元に作業している為仕方ない、これに手を加えない手段だと、手っ取り早いのはcomposeファイルでパスワードを設定してしまう方法なのでそれで対応。

もしシェルを改修して良ければ、こんな感じでやるかも

if [DB_PASSWORDが値関係なく(nullでも)定義が存在すれば]; then
    定義されているものを優先(nullでも)
else
    xxxxxxxxを使用する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【MySQL】rootユーザーがいなくてハマったので再インストール

djangoの勉強がてらwebアプリを作ろうと思い、本番デプロイはMySQLになるだろうから、ローカル環境でもMySQLにしようと触ってみると...
「rootユーザーがいない!!!」
となりハマってしまいました。

最終手段のアンインストールからの再インストールをしたのでその手順をメモ
(使用OSはMac)

rootユーザーがなぜかいない

MySQLはmacにインストール済みでした。
しかしどのタイミングでインストールしたのか忘れていました
(たぶん...プログラミングを勉強し始めた頃に訳もわからず、教科書に書いてある通りにインストールしたんじゃないかと..)

mysqlを起動してユーザーを見てみると...rootユーザーがいない

mysql> SELECT Host, User FROM mysql.user;
+-----------+------------------+
| Host      | User             |
+-----------+------------------+
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
+-----------+------------------+

rootユーザーがいない状態では、この表示をさせるのも自分に取っては一苦労だったので、ここからまとめていきます。

rootユーザーがいない状態でのmysqlユーザー表示方法

通常のmysqlのログイン手順

①サーバー起動

$ mysql.server start
Starting MySQL
 SUCCESS! 

②rootユーザーでログイン

mysql -u root -p

rootユーザーがいない場合のmysqlのログインからの表示手順

①認証なしでサーバー起動

/usr/local/bin/mysqld_safe --skip-grant-tables

②ログイン

mysql -u root

③ユーザー表示

SELECT Host, User FROM mysql.user;

rootユーザー作成できず

ログインまでは認証なしでmysqlを起動すればできることがわかりました。
ただ、問題は肝心のrootユーザー作成です。

色々記事を漁って出てきたのがこちらのコマンド

insert into user (user, host, password) values('root', 'localhost', PASSWORD('password'));

ただ、これを打つと

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '('password'))' at line 1

今のmysqlのバージョンだと通らないのか...?

もう少し調べて出てきたのがこのコマンド

CREATE USER 'root'@'localhost' IDENTIFIED BY 'password';

だけど

ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

認証なしのログインではできません的な感じか...?

今の自分の知識じゃ八方塞がりになったのでmysqlをアンインストールして、再インストールすることにしました。

アンインストール時にファイル削除を忘れずに

まずはmysqlをアンインストール

brew uninstall mysql

ただmysqlをアンインストールするだけだと、設定ファイルとかが残ってしまうようで、再インストールした時にrootユーザーがいない状態のままです。
なのでmysqlに関するファイルを全て削除します。

sudo rm -rf /usr/local/mysql
sudo rm -rf /Library/StartupItems/MYSQL
sudo rm -rf /Library/PreferencePanes/MySQL.prefPane
sudo rm -rf /Library/Receipts/mysql-.pkg
sudo rm -rf /usr/local/Cellar/mysql*
sudo rm -rf /usr/local/bin/mysql*
sudo rm -rf /usr/local/var/mysql*
sudo rm -rf /usr/local/etc/my.cnf
sudo rm -rf /usr/local/share/mysql*
sudo rm -rf /usr/local/opt/mysql*

MySQL再インストール

mysqlをアンインストールして、関連ファイルを全て削除したら次は再インストールです。

brew install mysql

初期設定

サーバー起動コマンド

mysql.server start

初期設定コマンド

mysql_secure_installation

これを実行すると下記のように聞かれるけど、とりあえずそのままEnter

Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: 

続いてrootユーザーのパスワード設定

Please set the password for root here.

New password: 

Re-enter new password: 

同じパスワードを入力します。このパスワードは忘れないように!!

後は色々聞かれるけどそのままEnter

By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : 

 ... skipping.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : 

 ... skipping.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : 

 ... skipping.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : 

 ... skipping.
All done! 

これで一応設定完了!!

rootユーザーがいるか確認

mysql> select user, host from mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+

いますね。
これでやっと開発がスタートできそうです!!

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

Gormでsql-migrateとseeder

はじめに 今回の記事はGO初心者エンジニアの自分が 勉強したことを書いていく記事になります。 間違いだらけかもしれないので注意 今回は Goのパッケージである Gormとsql-migrateを使用します。 DBはmysqlを使用 ※ dockerによる開発環境準備等は省きます Dockerfileに使用するパッケージの記載 FROM golang:latest WORKDIR /go/src/api/ RUN go get -u github.com/labstack/echo \ && go get github.com/jinzhu/gorm \ && go get -u github.com/go-sql-driver/mysql \ && go get github.com/rubenv/sql-migrate/... EXPOSE 8080 gormとmysqlとsql-migrateを入れています。 dbconfig.ymlを作成 development: dialect: mysql datasource: root:rootpass@tcp(db:3306)/go_db?charset=utf8&parseTime=true&loc=Asia%2FTokyo dir: db/migrations table: migrations 補足 dir: db/migrationsの欄はmigrations ファイルを作成する場所を記載する 今回は/db/migrationsフォルダ配下にmigrations ファイルが作成される  次にコンテナを起動 $ docker-compose up -d $ docker-compose exec app bash sql-migrateのコマンド実施 sql-migrate new テーブル名 このコマンドでmigrateファイルが作成される 例えば usersテーブルのmigrateファイルを作成したいなら sql-migrate new users これで作成されている db/migrations フォルダを見に行くと 中身が空のsqlファイルがあるはずです sqlを書く CREATE TABLE IF NOT EXISTS users ( id bigint AUTO_INCREMENT NOT NULL, name VARCHAR(255), email VARCHAR(255), created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP, deleted_at TIMESTAMP NULL DEFAULT NULL, PRIMARY KEY (id) ); -- +migrate Down DROP TABLE IF EXISTS users; 今回は id name emailのカラムを持つusersテーブルを作成 マイグレーションの実行 $ sql-migrate up 確認するには $ sql-migrate status +-----------------------------+-------------------------------+ | MIGRATION | APPLIED | +-----------------------------+-------------------------------+ | 20210115071437-user.sql | 2021-01-22 15:01:52 +0900 JST | +-----------------------------+-------------------------------+ これで実行されたmigrateファイルを確認できます。 seederの作成と実行 users_seed.goの作成 今回は3名ほどuserを追加しておきましょう package main import ( "fmt" "log" "time" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) type Users struct { Name string Email string CreatedAt time.Time UpdatedAt time.Time } //struct内は最初大文字で始まるように書く!!!! func seeds(db *gorm.DB) error { users := Users{Name: "abe", Email: "abe@abe.com", CreatedAt: time.Now(), UpdatedAt: time.Now()} if err := db.Create(&users).Error; err != nil { fmt.Printf("%+v", err) } users2 := Users{Name: "asou", Email: "asou@asou.com", CreatedAt: time.Now(), UpdatedAt: time.Now()} if err := db.Create(&users2).Error; err != nil { fmt.Printf("%+v", err) } users3 := Users{Name: "suga", Email: "suga@suga.com", CreatedAt: time.Now(), UpdatedAt: time.Now()} if err := db.Create(&users3).Error; err != nil { fmt.Printf("%+v", err) } return nil } func openConnection() *gorm.DB { db, err := gorm.Open("mysql", "root:rootpass@tcp(db:3306)/go_db?charset=utf8&parseTime=true&loc=Asia%2FTokyo") if err != nil { log.Fatalf("Couldn't establish database connection: %s", err) } return db } func main() { db := openConnection() defer db.Close() if err := seeds(db); err != nil { fmt.Printf("%+v", err) return } } 動かしましょう! $ go run user_seed.go これでmigrateとseederの実装は完了です! 参考サイト
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

パッケージ mysql-server は利用できません。 というエラーについて

こんにちは! 
独学でRailsアプリを作成し、AWS EC2上に手動でデプロイしたとき想像以上に大変だったので、出会った主なエラーとその解決方法を複数の記事に分けて記します。同じ様にエラーで悩んでいる方にとって参考になれば幸いです。

環境

ローカル環境
・Ruby 2.7.2
・Ruby on Rails 6.0.3
・MySQL 8.0.2
EC2上の環境
・OS:Amazon Linux 2

今回はこの記事を参考にデプロイしました。
https://hackmd.io/4_1NYUTBSaSsOC8cur7WhA?view

事象

EC2インスタンスにSSH通信でログインし以下のコマンドでパッケージをインストールしました。

$ sudo yum -y install git make gcc-c++ patch openssl-devel libyaml-devel libffi-devel libicu-devel libxml2 libxslt libxml2-devel libxslt-devel zlib-devel readline-devel mysql mysql-server mysql-devel ImageMagick ImageMagick-devel epel-release sqlite sqlite-devel

パッケージのインストールが進んでいく中ログの中に気になるメッセージがありました。

 パッケージ mysql-server は利用できません。

どういうことでしょうか。このままではMySQLを使うことができないことは自分でも理解できました。

解決方法

原因を突き止めるべく調べてみると、どうやらEC2インスタンスにはデフォルトでMariaDBが入っており、それと競合することからこのメッセージが出たということがわかりました。
つまり、MariaDBを削除すればMySQLがインストールできるのではないかと考え、以下のコマンドを実行しました。

$ sudo yum remove mariadb-libs
$ rm -rf /var/lib/mysql/
$ sudo yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
$ sudo yum -y install mysql-community-server

手順としては以下の通りです。
①MariaDBライブラリ
②データフォルダの削除
③MySQL公式のyumリポジトリの追加
④MySQLのインストール

そしてバージョン確認のコマンドを実行して、正常に出力されれば成功です。

$ mysqld --version

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

参考

https://weblabo.oscasierra.net/installing-mysql57-centos7-yum/
https://qiita.com/riekure/items/d667c707e8ca496f88e6

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

LaravelでDBに保存した画像を表示する方法

はじめに

前回Laravelで画像のパスをDBに保存する方法をご紹介したので、今回は画像を表示する方法関してご紹介していきたいと思います。

保存する方法に関しては以下の記事をご参考ください。
Laravelで画像をアップロードし、パスをDBに保存する方法

こちらでは、画像のパスがすでにDBに保存されている前提で進めており、ファイル名等は全て前回作成したものを利用していきます。

-各バージョン
-laravel 6.x
-PHP 7.4.9
-mySQL 5.7.30

コントローラーを記述する

今回はindexアクションを使っていきたいと思います。

DBファザード使用するため、useで宣言し、そのあとに書いていきます。

BookController
use Illuminate\Support\Facades\DB;

public function index()
{
  $books = DB::table('books')->orderBy('created_at', 'desc')->get();

  return view('index', compact('books'));
}

まず、前回作成したbooksテーブルのデータを取得し、orderBy()created_at、つまり作成した日時をdesc順に並べるように指定しています。descとはdescendの略で、下に降りるという意味になるので、指定することによって作成した日時が新しいものが先頭に来るようになります。
そして取得したものを$booksという変数に格納しています。

続いて格納したものをreturnでビューに渡すようにします。
index.blade.phpというビューをこのあと作成するので、indexを指定し、compact()メソッドで変数をビューに渡すことができるようになっています。compact()を使用するときは$マークはつけずに記述して問題ありません。

また、今回はデータが少ないため全てのデータを取得していますが、もしデータが多く一覧画面では一部のデータのみ表示させたい場合は、以下のように書くこともできます。

BookController
use Illuminate\Support\Facades\DB;

public function index()
{
  $books = DB::table('books')
  ->select('id','title', 'author', 'created_at') //ここを追加
  ->orderBy('created_at', 'desc')
  ->get();

  return view('index', compact('books'));
}

select()でデータを選択することができるので、表示したいカラム名を指定することができます。
この場合は別途、全てのデータを表示する画面を作成するといいでしょう。

ビューを作成する

新しくデータを表示するindex.blade.phpを作成し、一覧を表示させるコードを書いていきます。
なお、今回はデータが少ないので全てのデータが表示されるようにしていきます。

index.blade.php
@foreach('books' as 'book')
  <table>
    <tr>
      <th>タイトル</th><td>{{ $book->title }}</td>
    </tr>
    <tr>
      <th>作者</th><td>{{ $book->author }}</td>
    </tr>
    <tr>
      <th>投稿日</th><td>{{ $book->created_at }}</td>
    </tr>
    <tr>
      <th>画像</th><td><img src="{{ asset('uploads/books/' . $book->image) }}" alt="book-image"></td>
    </tr>
  </table>
endforeach

BookControllerでbooksテーブルのデータを$booksに格納しているので、データをforeachで回して表示するようにしています。
画像に関しては、DBには画像のパスしか保存されていないため、画像の保存先を指定する必要があります。画像は前回Publicフォルダ内のuploads/booksに保存したので、今回はそのように指定しています。
また、見えやすくするようにtableを使用しましたが、便宜に合わせてulpタグで表示することも可能です。

ルーティングを指定する

index.blade.phpに接続したら、BookController内のindexアクションが起動するようにします。

web.php
Route::get('index', 'BookController@index')->name('index');

以上で完成です!

さいごに

今回はDBに保存している画像のパスを表示させる方法に関して解説しました。

もっとこういうやり方あるよーという場合は、やさしくコメントで教えていただけるとありがたいです!
ここまで読んでくださりありがとうございました!

参考

Laravel Image CRUD : How to fetch the image in Laravel

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

chcp 65001 すると MySQLが日本語を受け付けてくれない

環境-1つめ:10.1.32-MariaDB , XAMPP v3.2.2 , Windows10 Enterprise
環境-2つめ:10.4.17-MariaDB , XAMPP v3.2.4 , Windows10 PRO

結論から書くと私の場合は chcp 65001 を使ってWindowsコマンドプロンプト上から utf-8 の入力をするのは避けたほうがいい気がする。となりました。

起こったこと

  • Windowsコマンドプロンプトから MySQL を操作する時、chcp 65001 でコマンドプロンプトの文字コードを utf-8 にすると MySQL が日本語(3バイトuft-8)を受け付けてくれない
  • 読み出し時の文字化けはない。
  • また chcp 932 のまま、MySQL内で set names cp932 をすればなにも問題は起きない。
  • ふたつの環境で再現する。
# chcp 65001
///// ウィンドウが変わる
Active code page: 65001

# mysql -u root -p

MariaDB [(none)]> USE db1
Database changed

///// insert を試みる
MariaDB [db1]> INSERT INTO tb10(num,name) VALUES(1,'佐藤');
    '>
    '>
    '>     ///// ← 処理が完了していない
    '> ;    ///// ← セミコロン入れても完了しない
    '>
    '> '    ///// ← よく見るとシングルクオーテーション抜けだと言われてるので入力する
    ->
    -> ;    ///// ← セミコロンを入れて完了しエラー文が出る
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

この挙動は insert だけではなく as句 による名付けや、他の構文内で日本語を使った場合でもほぼ変わらない。
(as句だとシングルクオーテーションのありなしで少し変わる)

MariaDB [db1]> SELECT name AS '名前' FROM tb10;
    '> '
    -> ;
ERROR 1054 (42S22): Unknown column 'name' in 'field list'

MariaDB [db1]> SELECT name AS 名前 FROM tb10;
    -> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

MariaDB [db1]> SELECT ROD('あ');
    '> '
    -> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

直接文字コードを書くことによる insert はできる

utf-8 を CHAR()関数によって変換することはできる。
また直接文字コードを書くことによる insert もできる。

MariaDB [db1]> SELECT CHAR(0xe38182 using utf8);
+---------------------------+
| CHAR(0xe38182 using utf8) |
+---------------------------+
| あ                        |
+---------------------------+
1 row in set (0.000 sec)

MariaDB [db1]> INSERT INTO tb10(num,name) VALUES(1,0xe38182e38184);
Query OK, 1 row affected (0.00 sec)

MariaDB [db1]> SELECT * FROM tb10;
+------+--------+
| num  | name   |
+------+--------+
|    1 | あい   |
+------+--------+
1 row in set (0.000 sec)
接続が utf8 でカラムが utf8 のとき、4bit文字が現れるとそこで文字が切れる現象を思い出す

参考:https://tmtms.hatenablog.com/entry/2016/09/06/mysql-utf8

日本語の後ろが読まれてないのでは? というわけで日本語の末尾から行を分けてinsertしてみる。

MariaDB [db1]> insert into tb10(num,name) values(3,'佐藤
    '> ');
Query OK, 1 row affected (0.011 sec)

MariaDB [db1]> select * from tb10;
+------+--------+
| num  | name   |
+------+--------+
|    1 | あい   |
|    2 | 鈴木   |
|    3 |
      |
+------+--------+
3 rows in set (0.000 sec)

受け付けてくれた。
……なんかおかしいけど。
ただinsertできたらこっちのもので出力させます。

MariaDB [db1]> SELECT * FROM tb10 INTO OUTFILE 'a.dmp';
Query OK, 3 rows affected, 1 warning (0.001 sec)

これをテキストと16進数とでそれぞれ見て……

>type a.dmp
1       あい
2       鈴木
3       \


>certutil -f -encodehex a.dmp a_16.txt 4
Input Length = 12
Output Length = 38
CertUtil: -encodehex command completed successfully.

>type a_16.txt
31 09 e3 81 82 e3 81 84  0a 32 09 e9 88 b4 e6 9c
a8 0a 33 09 5c 0a 0a

うん…………?

ちょっとわかりにくいので、新しく tb11 を作り2回insertします。

MariaDB [db1]> CREATE TABLE tb11(text VARCHAR(100));
Query OK, 0 rows affected (0.007 sec)

MariaDB [db1]> INSERT INTO tb11(text) VALUES('あい
    '> ');
Query OK, 1 row affected (0.003 sec)

MariaDB [db1]> INSERT INTO tb11(text) VALUES('高橋
    '> ');
Query OK, 1 row affected (0.001 sec)

MariaDB [db1]> SELECT * FROM tb11;
+------+
| text |
+------+
|
    |
|
    |
+------+
2 rows in set (0.000 sec)

MariaDB [db1]> SELECT * FROM tb11 INTO OUTFILE 'b.dmp';
Query OK, 2 rows affected, 1 warning (0.002 sec)

それをまたテキストファイルと16進数とで見て

>type b.dmp
\

\


>type b_16.txt
5c 0a 0a 5c 0a 0a

うん…………。
0a=<LF> の改行がひとつ多く入ってるのはシングルクォーテーションの間で一度改行してるのを正しく反映していると言えます。
その前、どんな文字を入れても 5c になってるのは、ちょっとわからない。

と、ここでお手上げになりました。

以下はMySQLの設定の確認

MySQL側の文字コードは utf-8 で統一されている(はず)

character_set の確認
MariaDB [(none)]> show global variables like 'char%';
+--------------------------+----------------------------------------------------------------+
| Variable_name            | Value                                                          |
+--------------------------+----------------------------------------------------------------+
| character_set_client     | utf8mb4                                                        |
| character_set_connection | utf8mb4                                                        |
| character_set_database   | utf8mb4                                                        |
| character_set_filesystem | binary                                                         |
| character_set_results    | utf8mb4                                                        |
| character_set_server     | utf8mb4                                                        |
| character_set_system     | utf8                                                           |
| character_sets_dir       | C:\ <--中略--> mysql\share\charsets\ |
+--------------------------+----------------------------------------------------------------+
8 rows in set (0.001 sec)

MariaDB [(none)]> show session variables like 'char%';
+--------------------------+----------------------------------------------------------------+
| Variable_name            | Value                                                          |
+--------------------------+----------------------------------------------------------------+
| character_set_client     | utf8mb4                                                        |
| character_set_connection | utf8mb4                                                        |
| character_set_database   | utf8mb4                                                        |
| character_set_filesystem | binary                                                         |
| character_set_results    | utf8mb4                                                        |
| character_set_server     | utf8mb4                                                        |
| character_set_system     | utf8                                                           |
| character_sets_dir       | C:\ <--中略--> mysql\share\charsets\ |
+--------------------------+----------------------------------------------------------------+
8 rows in set (0.000 sec)
その上で作られた db1
MariaDB [(none)]> select * from INFORMATION_SCHEMA.SCHEMATA where SCHEMA_NAME='db1';
+--------------+-------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+-------------+----------------------------+------------------------+----------+
| def          | db1         | utf8mb4                    | utf8mb4_unicode_ci     | NULL     |
+--------------+-------------+----------------------------+------------------------+----------+
1 row in set (0.002 sec)
その上で作られた tb10
MariaDB [db1]> show create table tb10;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                         |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tb10  | CREATE TABLE `tb10` (
  `num` int(11) DEFAULT NULL,
  `name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)
一応 my.ini の記述も置いておきます
[mysqld]
## UTF 8 Settings
init-connect='SET NAMES utf8mb4'
collation_server=utf8mb4_unicode_ci
character_set_server=utf8mb4
skip-character-set-client-handshake
character_sets-dir="C:/ <--中略--> mysql/share/charsets"
sql_mode=NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION
log_bin_trust_function_creators = 1

[mysqldump]
default-character-set   = utf8mb4

[mysql]
default-character-set   = utf8mb4

Shift_JIS のまま set names すれば問題は起きない

# chcp
現在のコード ページ: 932

# mysql -u root -p

MariaDB [(none)]> SET NAMES cp932;
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> USE db1
Database changed

MariaDB [db1]> INSERT INTO tb10(num,name) VALUES(2,'鈴木');
Query OK, 1 row affected (0.003 sec)

MariaDB [db1]> SELECT * from tb10;
+------+------+
| num  | name |
+------+------+
|    1 | あい     |
|    2 | 鈴木     |
+------+------+
2 rows in set (0.003 sec)

怪しいのは chcp 65001 かな…………

コマンドラインから MySQL に渡している文字列を16進数で抜き出す(どこかに出力させる)ことができればもう少しわかりそうなのですが。

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