Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
MySQLの文字コード事情MySQLの文字コード事情
2017版2017版
MySQL Casual Vol.10
2017/02/01
とみたまさひろ
MySQL Casual こわいMySQL Casual こわい
自己紹介自己紹介
とみた まさひろ
長野県北部在住プログラマー
好きなプログラミング言語 Ruby
Ruby/MySQLライブラリ
http://tmtms.hatenablog.com
http://twitter.com/tmtms
htt...
最近の活動最近の活動
Software Design 2016年6月号
「MySQLでデータベースを作ってみよう!」
Software Design 2016年9月号
「MySQL 4つのログの使いどころ」
Software Design 20...
MySQLに対する興味分野MySQLに対する興味分野
プロトコルプロトコル
X Protocol とか
文字コード文字コード
今回は文字コード今回は文字コード
MySQLで文字コードというMySQLで文字コードという
と Character set(Charset)と Character set(Charset)
Character set ?Character set ?
語源的には文字集合語源的には文字集合
文字集合文字集合
US-ASCII
数字、英字、32個の記号
JIS X 0201
US-ASCII(「」→「¥」/「~」→「‾」)+カタカ
ナ
JIS X 0208
数字、ひらがな、カタカナ、漢字、ラテン文字、
ギリシャ文字、記号等々
JIS...
文字集合文字集合
Windows-31J
JIS X 0201 + JIS X 0208 + NEC特殊文字 + IBM
拡張文字(「⑧」「Ⅷ」「㈱」「髙」「﨑」「彅」
等)
Unicode
世界中の文字。絵文字(「��������������...
あれ?あれ?
「CP932」とか「UTF-8」「CP932」とか「UTF-8」
は?は?
エンコーディングエンコーディング
文字符号化方式文字符号化方式
文字集合の文字をコンピュータで利用できるバイト列
に変換する方式
エンコーディングエンコーディング
Encoding 文字集合 用途
ISO-2022-JP US-ASCII, JIS X 0201(ラテン文
字), JIS X 0208
メール
EUC-JP US-ASCII, JIS X 0201(カナ文...
エンコーディングエンコーディング
Encoding 文字集合 1文字のサイズ
UTF-8 Unicode 1〜4バイト
UTF-16 Unicode 2バイト
UTF-32 Unicode 4バイト
Charset ≒ エンコーディングCharset ≒ エンコーディング
(MySQLに限らない)(MySQLに限らない)
MySQLのCharsetMySQLのCharset
mysql> SHOW CHARACTER SET;
+----------+---------------------------------+-----------------
| Ch...
日本語が使えてASCII互換の日本語が使えてASCII互換の
は ujis, sjis, eucjpms,は ujis, sjis, eucjpms,
cp932, utf8, utf8mb4cp932, utf8, utf8mb4
MySQL CharsetMySQL Charset
charset 文字集合 エンコーディング
ujis JIS X 0201 + 0208 EUC-JP
sjis JIS X 0201 + 0208 SHIFT_JIS
eucjpms Wi...
今なら普通はUnicode今なら普通はUnicode
世界中のほぼすべての文字を扱える
絵文字も使える
世の中もう普通にユニコード
文字コード変換とか考えなくていい
文字化けしない
utf8 ? utf8mb4 ?utf8 ? utf8mb4 ?
utf8 と utf8mb4utf8 と utf8mb4
utf8: 1文字 1〜3バイト (U+0000〜U+FFFF)
utf8mb3 という別名あり
utf8mb4: 1文字 1〜4バイト(U+0000〜U+1FFFFF)
UTF-8 は...
4バイトになる JIS X 02134バイトになる JIS X 0213
の文字の文字
𠀋𡈽𡌛𡑮𡢽𠮟𡚴𡸴𣇄𣗄𣜿𣝣𣳾𤟱𥒎𥔎𥝱𥧄𥶡𦫿𦹀𧃴𧚄𨉷𨏍𪆐𠂉
𠂢𠂤𠆢𠈓𠌫𠎁𠍱𠏹𠑊𠔉𠗖𠘨𠝏𠠇𠠺𠢹𠥼𠦝𠫓𠬝𠵅𠷡𠺕𠹭𠹤𠽟𡈁
𡉕𡉻𡉴𡋤𡋗𡋽𡌶𡍄𡏄𡑭𡗗𦰩𡙇𡜆𡝂𡧃𡱖𡴭𡵅𡵸𡵢𡶡...
4バイトになる絵文字(一部)4バイトになる絵文字(一部)
���������������������������������������������������������������������������������������������...
MySQLのCharsetMySQLのCharset
サーバー
クライアント
サーバー/クライアント間の接続
データベース毎
テーブル毎
カラム毎
…を全部別々に設定できる(嫌な予感しかしない)
ハマりたくなければ全部統一ハマりたくなければ全部統一
サーバー Charsetサーバー Charset
新規に作成するデータベースのCharsetのデフォルト
これさえ指定しておけばだいたいOK
mysqld の起動オプション
--character-set-server=utf8mb4
my.c...
データベース Charsetデータベース Charset
配下に作成するテーブルのCharsetのデフォルト値
サーバーCharsetと同じであれば指定しなくてもいい
作成: CREATE DATABASE db CHARSET utf8mb4...
テーブル Charsetテーブル Charset
テーブル内カラムのCharsetのデフォルト値
データベースCharsetと同じであれば指定する必要は
ない
作成: CREATE TABLE tbl (...) CHARSET utf8mb4...
テーブル Charsetテーブル Charset
テーブル属性だけ変更:
ALTER TABLE tbl CHARSET utf8mb4;
既存のカラムのcharsetは変更されない
全カラムとデータの変換:
ALTER TABLE tbl C...
カラム Charsetカラム Charset
テーブルCharsetと同じであれば指定する必要はない
作成: CREATE TABLE tbl (col VARCHAR(10) CHARSET
utf8mb4, ...);
確認: SHOW C...
クライアント Charsetクライアント Charset
クライアント内での文字列処理と
サーバーとの接続Charsetに使用される
指定方法はプログラム/言語に依存
mysql --default-character-set=utf8mb4
...
クライアント Charsetクライアント Charset
mysqld との接続毎に異なる
mysql コマンドでOKでも他のアプリからはNGかも
しれない
何も指定しなければ latin1
Charset の確認Charset の確認
mysql> SHOW VARIABLES LIKE '%char%';
+--------------------------+----------------------------+
| Va...
mysql コマンドmysql コマンド
mysql コマンドのデフォルトCharsetは auto
システムロケール(LC_ALL, LC_CTYPE, LANG 環境
変数等)により値が決定
LANG=ja_JP.UTF-8 の場合は ut...
utf8 と utf8mb4 の混在でutf8 と utf8mb4 の混在で
起きること起きること
utf8接続から4バイト文字をutf8接続から4バイト文字を
参照参照
クライアントが扱えない文字は「?」になる
mysql> SELECT str FROM tbl;
+-------+
| str |
+-------+
| ?と? | ←...
バイト列を見れば違いがわかバイト列を見れば違いがわか
るる
mysql> SELECT HEX(str) FROM tbl;
+------------------------+
| HEX(str) |
+------------------...
utf8接続から4バイト文字をutf8接続から4バイト文字を
登録登録
文字化けして登録されちゃう
mysql> INSERT INTO tbl (str) VALUES ('�������������������と��������������...
sql_modesql_mode
MySQLはおかしなことしてもあまりエラーにならな
い(余計なお世話)
sql_mode でちゃんとエラーにしてくれる
mysql> SET sql_mode='STRICT_ALL_TABLES';
mysq...
sql_modesql_mode
MySQL 5.7 からはデフォルト
mysql> SELECT @@sql_mode
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE
NO_ZER...
�������������������=����������������� 問題
�������������������と�����������������以外でも
mysql> SELECT '����������'='�������������';
+---------+
| '?'='?' |
+---------+
...
実は未知の文字�扱い実は未知の文字�扱い
‘�������������������’=’�����������������’=’�’
CollationCollation
CollationCollation
文字の照合規則・照合順序
Charset 毎に Collation がある
Charset の指定は Charset のデフォルトの
Collation を指定するのと同じ
Collation 一覧Collation 一覧
mysql> SHOW COLLATION LIKE 'utf8mb4%';
+------------------------+---------+-----+---------+------...
utf8mb4 の Collationutf8mb4 の Collation
utf8mb4_general_ci
utf8mb4_bin
utf8mb4_unicode_ci
utf8mb4_unicode_520_ci
utf8mb4_言語...
utf8mb4_general_ciutf8mb4_general_ci
utf8mb4 Charset のデフォルト Collation
大文字小文字を区別しない(A=a, A=a)
全角半角は区別する(A≠A)
絵文字を区別しない(����...
utf8mb4_binutf8mb4_bin
varchar(n) binary
全文字を区別する(A≠a, �������������������≠�����������������)
utf8mb4_unicode_ciutf8mb4_unicode_ci
Unicode Collation Algorithm 4.0.0
大文字小文字を区別しない(A=a, A=a)
全角半角も区別しない(A=A)
絵文字を区別しない(��...
utf8mb4_unicode_520_ciutf8mb4_unicode_520_ci
Unicode Collation Algorithm 5.2.0
大文字小文字を区別しない(A=a, A=a)
全角半角も区別しない(A=A)
絵文字を...
utf8mb4_*utf8mb4_*
Collation A : a ������������������� : ����������������� は : ば
ぱ : ハ
general_ci = = ≠
bin ≠ ≠ ≠
unicode_...
utf8mb4_*utf8mb4_*
Collation A : a ������������������� : ����������������� は : ば
ぱ : ハ
general_ci = = ≠
bin ≠ ≠ ≠
unicode_...
寿司=ビール問題 : MySQL 8.0でのUTF8寿司=ビール問題 : MySQL 8.0でのUTF8
サポート入門(MySQL Server Blogより)サポート入門(MySQL Server Blogより)
https://yakst....
まとめまとめ
ふつうは utf8mb4
サーバーとクライアントの両方で Charset を指定
sql_mode をちゃんと設定
Collation は適切に
MySQL 8 で unicode_japanese_ci ができるかも!?
Upcoming SlideShare
Loading in …5
×

MySQLの文字コード事情 2017版

25,516 views

Published on

MySQL Casual vol.10 での発表スライド

Published in: Technology
  • Be the first to comment

MySQLの文字コード事情 2017版

  1. 1. MySQLの文字コード事情MySQLの文字コード事情 2017版2017版 MySQL Casual Vol.10 2017/02/01 とみたまさひろ
  2. 2. MySQL Casual こわいMySQL Casual こわい
  3. 3. 自己紹介自己紹介 とみた まさひろ 長野県北部在住プログラマー 好きなプログラミング言語 Ruby Ruby/MySQLライブラリ http://tmtms.hatenablog.com http://twitter.com/tmtms https://github.com/tmtm
  4. 4. 最近の活動最近の活動 Software Design 2016年6月号 「MySQLでデータベースを作ってみよう!」 Software Design 2016年9月号 「MySQL 4つのログの使いどころ」 Software Design 2016年12月号 「Rubyと文字コード」 「MySQLと文字コード」 mysql.gr.jp ドメイン料支払い
  5. 5. MySQLに対する興味分野MySQLに対する興味分野 プロトコルプロトコル X Protocol とか 文字コード文字コード
  6. 6. 今回は文字コード今回は文字コード
  7. 7. MySQLで文字コードというMySQLで文字コードという と Character set(Charset)と Character set(Charset)
  8. 8. Character set ?Character set ?
  9. 9. 語源的には文字集合語源的には文字集合
  10. 10. 文字集合文字集合 US-ASCII 数字、英字、32個の記号 JIS X 0201 US-ASCII(「」→「¥」/「~」→「‾」)+カタカ ナ JIS X 0208 数字、ひらがな、カタカナ、漢字、ラテン文字、 ギリシャ文字、記号等々 JIS X 0213 JIS X 0208 + 第三水準/第四水準、ローマ数字、 鼻濁音文字等々
  11. 11. 文字集合文字集合 Windows-31J JIS X 0201 + JIS X 0208 + NEC特殊文字 + IBM 拡張文字(「⑧」「Ⅷ」「㈱」「髙」「﨑」「彅」 等) Unicode 世界中の文字。絵文字(「�����������������」「�������������������」等)も含む。
  12. 12. あれ?あれ? 「CP932」とか「UTF-8」「CP932」とか「UTF-8」 は?は?
  13. 13. エンコーディングエンコーディング 文字符号化方式文字符号化方式 文字集合の文字をコンピュータで利用できるバイト列 に変換する方式
  14. 14. エンコーディングエンコーディング Encoding 文字集合 用途 ISO-2022-JP US-ASCII, JIS X 0201(ラテン文 字), JIS X 0208 メール EUC-JP US-ASCII, JIS X 0201(カナ文字), JIS X 0208, JIS X 0212 昔の UNIX SHIFT_JIS JIS X 0201, JIS X 0208 Windows-31J CP932 Windows-31J Windows
  15. 15. エンコーディングエンコーディング Encoding 文字集合 1文字のサイズ UTF-8 Unicode 1〜4バイト UTF-16 Unicode 2バイト UTF-32 Unicode 4バイト
  16. 16. Charset ≒ エンコーディングCharset ≒ エンコーディング (MySQLに限らない)(MySQLに限らない)
  17. 17. MySQLのCharsetMySQLのCharset mysql> SHOW CHARACTER SET; +----------+---------------------------------+----------------- | Charset | Description | Default collatio +----------+---------------------------------+----------------- | big5 | Big5 Traditional Chinese | big5_chinese_ci | dec8 | DEC West European | dec8_swedish_ci | cp850 | DOS West European | cp850_general_ci | hp8 | HP West European | hp8_english_ci | koi8r | KOI8-R Relcom Russian | koi8r_general_ci | latin1 | cp1252 West European | latin1_swedish_c | latin2 | ISO 8859-2 Central European | latin2_general_c | swe7 | 7bit Swedish | swe7_swedish_ci | ascii | US ASCII | ascii_general_ci
  18. 18. 日本語が使えてASCII互換の日本語が使えてASCII互換の は ujis, sjis, eucjpms,は ujis, sjis, eucjpms, cp932, utf8, utf8mb4cp932, utf8, utf8mb4
  19. 19. MySQL CharsetMySQL Charset charset 文字集合 エンコーディング ujis JIS X 0201 + 0208 EUC-JP sjis JIS X 0201 + 0208 SHIFT_JIS eucjpms Windows-31J EUC-JP風 cp932 Windows-31J Windows-31J utf8 Unicode UTF-8 utf8mb4 Unicode UTF-8
  20. 20. 今なら普通はUnicode今なら普通はUnicode 世界中のほぼすべての文字を扱える 絵文字も使える 世の中もう普通にユニコード 文字コード変換とか考えなくていい 文字化けしない
  21. 21. utf8 ? utf8mb4 ?utf8 ? utf8mb4 ?
  22. 22. utf8 と utf8mb4utf8 と utf8mb4 utf8: 1文字 1〜3バイト (U+0000〜U+FFFF) utf8mb3 という別名あり utf8mb4: 1文字 1〜4バイト(U+0000〜U+1FFFFF) UTF-8 は普通1〜4バイト utf8 / utf8mb4 の違いは MySQL のみ ほとんどの日本語文字は3バイト 一部の漢字と絵文字等が4バイト
  23. 23. 4バイトになる JIS X 02134バイトになる JIS X 0213 の文字の文字 𠀋𡈽𡌛𡑮𡢽𠮟𡚴𡸴𣇄𣗄𣜿𣝣𣳾𤟱𥒎𥔎𥝱𥧄𥶡𦫿𦹀𧃴𧚄𨉷𨏍𪆐𠂉 𠂢𠂤𠆢𠈓𠌫𠎁𠍱𠏹𠑊𠔉𠗖𠘨𠝏𠠇𠠺𠢹𠥼𠦝𠫓𠬝𠵅𠷡𠺕𠹭𠹤𠽟𡈁 𡉕𡉻𡉴𡋤𡋗𡋽𡌶𡍄𡏄𡑭𡗗𦰩𡙇𡜆𡝂𡧃𡱖𡴭𡵅𡵸𡵢𡶡𡶜𡶒𡶷𡷠𡸳 𡼞𡽶𡿺𢅻𢌞𢎭𢛳𢡛𢢫𢦏𢪸𢭏𢭐𢭆𢰝𢮦𢰤𢷡𣇃𣇵𣆶𣍲𣏓𣏒𣏐𣏤𣏕 𣏚𣏟𣑊𣑑𣑋𣑥𣓤𣕚𣖔𣘹𣙇𣘸𣘺𣜜𣜌𣝤𣟿𣟧𣠤𣠽𣪘𣱿𣴀𣵀𣷺𣷹𣷓 𣽾𤂖𤄃𤇆𤇾𤎼𤘩𤚥𤢖𤩍𤭖𤭯𤰖𤴔𤸎𤸷𤹪𤺋𥁊𥁕𥄢𥆩𥇥𥇍𥈞𥉌𥐮 𥓙𥖧𥞩𥞴𥧔𥫤𥫣𥫱𥮲𥱋𥱤𥸮𥹖𥹥𥹢𥻘𥻂𥻨𥼣𥽜𥿠𥿔𦀌𥿻𦀗𦁠𦃭 𦉰𦊆𦍌𣴎𦐂𦙾𦚰𦜝𦣝𦣪𦥑𦥯𦧝𦨞𦩘𦪌𦪷𦱳𦳝𦹥𦾔𦿸𦿶𦿷𧄍𧄹𧏛 𧏚𧏾𧐐𧑉𧘕𧘔𧘱𧚓𧜎𧜣𧝒𧦅𧪄𧮳𧮾𧯇𧲸𧶠𧸐𧾷𨂊𨂻𨊂𨋳𨐌𨑕𨕫 𨗈𨗉𨛗𨛺𨥉𨥆𨥫𨦇𨦈𨦺𨦻𨨞𨨩𨩱𨩃𨪙𨫍𨫤𨫝𨯁𨯯𨴐𨵱𨷻𨸟𨸶𨺉 𨻫𨼲𨿸𩊠𩊱𩒐𩗏𩙿𩛰𩜙𩝐𩣆𩩲𩷛𩸽𩸕𩺊𩹉𩻄𩻩𩻛𩿎𪀯𪀚𪃹𪂂𢈘 𪎌𪐷𪗱𪘂𪘚𪚲
  24. 24. 4バイトになる絵文字(一部)4バイトになる絵文字(一部) ����������������������������������������������������������������������������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������������������������������������������ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ����������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
  25. 25. MySQLのCharsetMySQLのCharset サーバー クライアント サーバー/クライアント間の接続 データベース毎 テーブル毎 カラム毎 …を全部別々に設定できる(嫌な予感しかしない)
  26. 26. ハマりたくなければ全部統一ハマりたくなければ全部統一
  27. 27. サーバー Charsetサーバー Charset 新規に作成するデータベースのCharsetのデフォルト これさえ指定しておけばだいたいOK mysqld の起動オプション --character-set-server=utf8mb4 my.cnf の [mysqld] セクション character-set-server = utf8mb4 サーバー変数 character_set_server
  28. 28. データベース Charsetデータベース Charset 配下に作成するテーブルのCharsetのデフォルト値 サーバーCharsetと同じであれば指定しなくてもいい 作成: CREATE DATABASE db CHARSET utf8mb4; 確認: SHOW CREATE DATABASE db; 変更: ALTER DATABASE db CHARSET utf8mb4; 変更しても既存のテーブルCharsetは変更されない
  29. 29. テーブル Charsetテーブル Charset テーブル内カラムのCharsetのデフォルト値 データベースCharsetと同じであれば指定する必要は ない 作成: CREATE TABLE tbl (...) CHARSET utf8mb4; 確認: SHOW CREATE TABLE tbl;
  30. 30. テーブル Charsetテーブル Charset テーブル属性だけ変更: ALTER TABLE tbl CHARSET utf8mb4; 既存のカラムのcharsetは変更されない 全カラムとデータの変換: ALTER TABLE tbl CONVERT TO CHARSET utf8mb4; utf8 で作ってしまったテーブルを utf8mb4 に変 換とか
  31. 31. カラム Charsetカラム Charset テーブルCharsetと同じであれば指定する必要はない 作成: CREATE TABLE tbl (col VARCHAR(10) CHARSET utf8mb4, ...); 確認: SHOW CREATE TABLE tbl; 変更: ALTER TABLE tbl MODIFY col VARCHAR(10) CHARSET utf8mb4; 変更するとカラム内のデータも変換される
  32. 32. クライアント Charsetクライアント Charset クライアント内での文字列処理と サーバーとの接続Charsetに使用される 指定方法はプログラム/言語に依存 mysql --default-character-set=utf8mb4 プログラムによっては my.cnf の [client] セクショ ンが有効 「loose-」をつけておくとそのパラメータを知らないプログラムは 無視してくれる [client] loose-default-character-set = utf8mb4
  33. 33. クライアント Charsetクライアント Charset mysqld との接続毎に異なる mysql コマンドでOKでも他のアプリからはNGかも しれない 何も指定しなければ latin1
  34. 34. Charset の確認Charset の確認 mysql> SHOW 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 | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+
  35. 35. mysql コマンドmysql コマンド mysql コマンドのデフォルトCharsetは auto システムロケール(LC_ALL, LC_CTYPE, LANG 環境 変数等)により値が決定 LANG=ja_JP.UTF-8 の場合は utf8 になる utf8mb4 ではない LANG=C の場合は latin1 になる
  36. 36. utf8 と utf8mb4 の混在でutf8 と utf8mb4 の混在で 起きること起きること
  37. 37. utf8接続から4バイト文字をutf8接続から4バイト文字を 参照参照 クライアントが扱えない文字は「?」になる mysql> SELECT str FROM tbl; +-------+ | str | +-------+ | ?と? | ← '�������������������と�����������������' | ?と? | ← '?と?' +-------+
  38. 38. バイト列を見れば違いがわかバイト列を見れば違いがわか るる mysql> SELECT HEX(str) FROM tbl; +------------------------+ | HEX(str) | +------------------------+ | F09F8DA3E381A8F09F8DBA | ← '�������������������と�����������������' | 3FE381A83F | ← '?と?' +------------------------+
  39. 39. utf8接続から4バイト文字をutf8接続から4バイト文字を 登録登録 文字化けして登録されちゃう mysql> INSERT INTO tbl (str) VALUES ('�������������������と�����������������'); Query OK, 1 row affected, 2 warnings (0.05 sec) mysql> SELECT str,HEX(str) FROM tbl; +-------------+------------------------+ | str | HEX(str) | +-------------+------------------------+ | ????と???? | 3F3F3F3FE381A83F3F3F3F | +-------------+------------------------+
  40. 40. sql_modesql_mode MySQLはおかしなことしてもあまりエラーにならな い(余計なお世話) sql_mode でちゃんとエラーにしてくれる mysql> SET sql_mode='STRICT_ALL_TABLES'; mysql> INSERT INTO tbl (str) VALUES ('�������������������と�����������������'); ERROR 1366 (HY000): Incorrect string value: 'xF0x9Fx8DxA3xE3x81...' for column 'str' at row 1
  41. 41. sql_modesql_mode MySQL 5.7 からはデフォルト mysql> 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
  42. 42. �������������������=����������������� 問題
  43. 43. �������������������と�����������������以外でも mysql> SELECT '����������'='�������������'; +---------+ | '?'='?' | +---------+ | 1 | +---------+ mysql> SELECT '����������'='�����'; +---------+ | '?'='?' | +---------+ | 1 | +---------+
  44. 44. 実は未知の文字�扱い実は未知の文字�扱い ‘�������������������’=’�����������������’=’�’
  45. 45. CollationCollation
  46. 46. CollationCollation 文字の照合規則・照合順序 Charset 毎に Collation がある Charset の指定は Charset のデフォルトの Collation を指定するのと同じ
  47. 47. Collation 一覧Collation 一覧 mysql> SHOW COLLATION LIKE 'utf8mb4%'; +------------------------+---------+-----+---------+----------+ | Collation | Charset | Id | Default | Compiled | +------------------------+---------+-----+---------+----------+ | utf8mb4_general_ci | utf8mb4 | 45 | Yes | Yes | | utf8mb4_bin | utf8mb4 | 46 | | Yes | | utf8mb4_unicode_ci | utf8mb4 | 224 | | Yes | | utf8mb4_icelandic_ci | utf8mb4 | 225 | | Yes | | utf8mb4_latvian_ci | utf8mb4 | 226 | | Yes | | utf8mb4_romanian_ci | utf8mb4 | 227 | | Yes | | utf8mb4_slovenian_ci | utf8mb4 | 228 | | Yes | | utf8mb4_polish_ci | utf8mb4 | 229 | | Yes | | utf8mb4_estonian_ci | utf8mb4 | 230 | | Yes |
  48. 48. utf8mb4 の Collationutf8mb4 の Collation utf8mb4_general_ci utf8mb4_bin utf8mb4_unicode_ci utf8mb4_unicode_520_ci utf8mb4_言語_ci utf8mb4_japanese_ci は無い 「ci」は Case Insensitive(大文字小文字を区別しない) の意味らしい
  49. 49. utf8mb4_general_ciutf8mb4_general_ci utf8mb4 Charset のデフォルト Collation 大文字小文字を区別しない(A=a, A=a) 全角半角は区別する(A≠A) 絵文字を区別しない(�������������������=�����������������)
  50. 50. utf8mb4_binutf8mb4_bin varchar(n) binary 全文字を区別する(A≠a, �������������������≠�����������������)
  51. 51. utf8mb4_unicode_ciutf8mb4_unicode_ci Unicode Collation Algorithm 4.0.0 大文字小文字を区別しない(A=a, A=a) 全角半角も区別しない(A=A) 絵文字を区別しない(�������������������=�����������������) ひらがな、カタカナ、濁点有無、全角、半角を区別 しない(は=ば=ぱ=ハ=バ=パ=ハ) 「ハハ=パパ=ババ問題」 http://www.unicode.org/reports/tr10/tr10-11.html http://dev.mysql.com/doc/refman/5.6/ja/charset-unicode-sets.html
  52. 52. utf8mb4_unicode_520_ciutf8mb4_unicode_520_ci Unicode Collation Algorithm 5.2.0 大文字小文字を区別しない(A=a, A=a) 全角半角も区別しない(A=A) 絵文字を区別する(�������������������≠�����������������) ひらがな、カタカナ、濁点有無、全角、半角を区別 しない(は=ば=ぱ=ハ=バ=パ=ハ) http://www.unicode.org/reports/tr10/tr10-20.html
  53. 53. utf8mb4_*utf8mb4_* Collation A : a ������������������� : ����������������� は : ば ぱ : ハ general_ci = = ≠ bin ≠ ≠ ≠ unicode_ci = = = unicode_520_ci = ≠ =
  54. 54. utf8mb4_*utf8mb4_* Collation A : a ������������������� : ����������������� は : ば ぱ : ハ general_ci = = ≠ bin ≠ ≠ ≠ unicode_ci = = = unicode_520_ci = ≠ = ぼくたちが欲しかった japanese_ci = ≠ ≠
  55. 55. 寿司=ビール問題 : MySQL 8.0でのUTF8寿司=ビール問題 : MySQL 8.0でのUTF8 サポート入門(MySQL Server Blogより)サポート入門(MySQL Server Blogより) https://yakst.com/ja/posts/4405 私たちは日本語の照合順序の追加も計 画中です。日本語は興味深い言語であ り、私たちの照合順序のエキスパート であるXing ZhangとBernt Marius Johnsenが、今後のブログ記事でもっ と詳しく説明するはずです。
  56. 56. まとめまとめ ふつうは utf8mb4 サーバーとクライアントの両方で Charset を指定 sql_mode をちゃんと設定 Collation は適切に MySQL 8 で unicode_japanese_ci ができるかも!?

×