More Related Content Similar to MySQLの文字コード事情 (20) More from Masahiro Tomita More from Masahiro Tomita (20) MySQLの文字コード事情2. MySQLの文字コード事情 Powered by Rabbit 2.1.9
自己紹介
とみた まさひろ
http://tmtms.hatenablog.com
http://twitter.com/tmtms
https://github.com/tmtm
長野県北部在住プログラマー( Ruby & C )
長野ソフトウェア技術者グループ(NSEG)
日本MySQLユーザ会代表
6. MySQLの文字コード事情 Powered by Rabbit 2.1.9
MySQL Charset
文字集合\エンコーディング
EUC シフトJIS UTF-8
JIS ujis sjis ―
Windows-
31J
eucjp cp932 ―
Unicode ― ― utf8
utf8mb4
7. MySQLの文字コード事情 Powered by Rabbit 2.1.9
文字集合
JIS
日本語+α (JIS X 0201, JIS X 0208, (JIS X 0212))
Windows-31J
JIS + NEC特殊文字 + IBM拡張文字(「①」「㈱」「髙」等
)
Unicode
世界中の文字。絵文字(「🍺」「🍣」等)も含む
8. MySQLの文字コード事情 Powered by Rabbit 2.1.9
エンコーディング
EUC
1〜3バイト。その昔UNIX系OSで日本語を扱うのに使わ
れていた
シフトJIS
1〜2バイト。Windowsで使われている
UTF-8
1〜4バイト。UnicodeのエンコーディングのうちASCII
互換
10. MySQLの文字コード事情 Powered by Rabbit 2.1.9
MySQL Charset (再掲)
文字集合\エンコーディング
EUC シフトJIS UTF-8
JIS ujis sjis ―
Windows-
31J
eucjp cp932 ―
Unicode ― ― utf8
utf8mb4
12. MySQLの文字コード事情 Powered by Rabbit 2.1.9
utf8 と utf8mb4
utf8: 1文字 1〜3バイト (U+0000〜U+FFFF)
utf8mb4: 1文字 1〜4バイト
(U+0000〜U+1FFFFF)
UTF-8 は普通1〜4バイト
utf8 / utf8mb4 の違いは MySQL のみ
ほとんどの日本語文字は3バイト
一部の漢字と絵文字等が4バイト
13. MySQLの文字コード事情 Powered by Rabbit 2.1.9
JIS X 0213 の文字の中で UTF-8 で 4バイトになるもの
𠀋𡈽𡌛𡑮𡢽𠮟𡚴𡸴𣇄𣗄𣜿𣝣𣳾𤟱𥒎𥔎𥝱𥧄𥶡𦫿𦹀𧃴𧚄𨉷𨏍
𪆐𠂉𠂢𠂤𠆢𠈓𠌫𠎁𠍱𠏹𠑊𠔉𠗖𠘨𠝏𠠇𠠺𠢹𠥼𠦝𠫓𠬝𠵅𠷡𠺕
𠹭𠹤𠽟𡈁𡉕𡉻𡉴𡋤𡋗𡋽𡌶𡍄𡏄𡑭𡗗𦰩𡙇𡜆𡝂𡧃𡱖𡴭𡵅𡵸𡵢
𡶡𡶜𡶒𡶷𡷠𡸳𡼞𡽶𡿺𢅻𢌞𢎭𢛳𢡛𢢫𢦏𢪸𢭏𢭐𢭆𢰝𢮦𢰤𢷡𣇃
𣇵𣆶𣍲𣏓𣏒𣏐𣏤𣏕𣏚𣏟𣑊𣑑𣑋𣑥𣓤𣕚𣖔𣘹𣙇𣘸𣘺𣜜𣜌𣝤𣟿
𣟧𣠤𣠽𣪘𣱿𣴀𣵀𣷺𣷹𣷓𣽾𤂖𤄃𤇆𤇾𤎼𤘩𤚥𤢖𤩍𤭖𤭯𤰖𤴔𤸎
𤸷𤹪𤺋𥁊𥁕𥄢𥆩𥇥𥇍𥈞𥉌𥐮𥓙𥖧𥞩𥞴𥧔𥫤𥫣𥫱𥮲𥱋𥱤𥸮𥹖
𥹥𥹢𥻘𥻂𥻨𥼣𥽜𥿠𥿔𦀌𥿻𦀗𦁠𦃭𦉰𦊆𦍌𣴎𦐂𦙾𦚰𦜝𦣝𦣪𦥑
𦥯𦧝𦨞𦩘𦪌𦪷𦱳𦳝𦹥𦾔𦿸𦿶𦿷𧄍𧄹𧏛𧏚𧏾𧐐𧑉𧘕𧘔𧘱𧚓𧜎
𧜣𧝒𧦅𧪄𧮳𧮾𧯇𧲸𧶠𧸐𧾷𨂊𨂻𨊂𨋳𨐌𨑕𨕫𨗈𨗉𨛗𨛺𨥉𨥆𨥫
𨦇𨦈𨦺𨦻𨨞𨨩𨩱𨩃𨪙𨫍𨫤𨫝𨯁𨯯𨴐𨵱𨷻𨸟𨸶𨺉𨻫𨼲𨿸𩊠𩊱
𩒐𩗏𩙿𩛰𩜙𩝐𩣆𩩲𩷛𩸽𩸕𩺊𩹉𩻄𩻩𩻛𩿎𪀯𪀚𪃹𪂂𢈘𪎌𪐷𪗱
𪘂𪘚𪚲
14. MySQLの文字コード事情 Powered by Rabbit 2.1.9
UTF-8 で4バイトになる絵文字(一部)
🀀🀁🀂🀃🀄🀅🀆🀇🀈🀉🀊🀋🀌🀍🀎🀏🀐🀑🀒🀓🀔🀕🀖🀗🀘🀙🀚🀛🀜🀝🀞
🀟🀠🀡🀢🀣🀤🀥🀦🀧🀨🀩🀪🀫🂠🂡🂢🂣🂤🂥🂦🂧🂨🂩🂪🂫🂬🂭
🂮🂱🂲🂳🂴🂵🂶🂷🂸🂹🂺🂻🂼🂽🂾🂿🃁🃂🃃🃄🃅🃆🃇🃈
🃉🃊🃋🃌🃍🃎🃏🃑🃒🃓🃔🃕🃖🃗🃘🃙🃚🃛🃜🃝🃞🃟🈀🈁
🈂🈐🈑🈒🈓🈔🈕🈖🈗🈘🈙🈚🈛🈜🈝🈞🈟🈠🈡🈢🈣🈤🈥🈦
🈧🈨🈩🈪🈫🈬🈭🈮🈯🈰🈱🈲🈳🈴🈵🈶🈷🈸🈹🈺🉀🉁🉂🉃
🉄🉅🉆🉇🉈🉐🉑🌀🌁🌂🌃🌄🌅🌆🌇🌈🌉🌊🌋🌌🌍🌎🌏🌐
🌑🌒🌓🌔🌕🌖🌗🌘🌙🌚🌛🌜🌝🌞🌟🌠🌡🌢🌣🌤🌥🌦🌧🌨🌩🌪
🌫🌬🌭🌮🌯🌰🌱🌲🌳🌴🌵🌶🌷🌸🌹🌺🌻🌼🌽🌾🌿🍀🍁🍂🍃🍄
🍅🍆🍇🍈🍉🍊🍋🍌🍍🍎🍏🍐🍑🍒🍓🍔🍕🍖🍗🍘🍙🍚🍛🍜🍝
🍞🍟🍠🍡🍢🍣🍤🍥🍦🍧🍨🍩🍪🍫🍬🍭🍮🍯🍰🍱🍲🍳🍴🍵🍶🍷
🍸🍹🍺🍻🍼🍽🍾🍿🎀🎁🎂🎃🎄🎅🎆🎇🎈🎉🎊🎋🎌🎍🎎🎏🎐🎑
🎒🎓🎔🎕🎖🎗🎘🎙🎚🎛🎜🎝🎞🎟🎠🎡🎢🎣🎤🎥🎦🎧🎨🎩🎪🎫
🎬🎭🎮🎯🎰🎱🎲🎳🎴🎵🎶🎷🎸🎹🎺🎻🎼🎽🎾🎿🏀🏁🏂🏃🏄🏅
🏆🏇🏈🏉🏊🏋🏌🏍🏎🏏🏐🏑🏒🏓🏔🏕
18. MySQLの文字コード事情 Powered by Rabbit 2.1.9
サーバー Charset
新規作成データベースのCharsetのデフォルト値
これさえ指定しておけばだいたいOK
mysqld の起動オプション
--character-set-server=utf8mb4
my.cnf の [mysqld] セクション
character-set-server = utf8mb4
サーバー変数 character_set_server
19. MySQLの文字コード事情 Powered by Rabbit 2.1.9
データベース Charset
配下に作成するテーブルのCharsetのデフォルト値
サーバーCharsetが適切に設定されてれば指定しなく
てもいい
作成:
CREATE DATABASE db CHARSET utf8mb4;
確認:
SHOW CREATE DATABASE db;
20. MySQLの文字コード事情 Powered by Rabbit 2.1.9
データベース Charset
変更:
ALTER DATABASE db CHARSET utf8mb4;
変更しても既存のテーブルCharsetは変更されない
21. MySQLの文字コード事情 Powered by Rabbit 2.1.9
テーブル Charset
テーブル内カラムのCharsetのデフォルト値
データベースCharsetが適切に設定されてれば指定す
る必要はない
作成:
CREATE TABLE tbl (...) CHARSET utf8mb4;
確認:
SHOW CREATE TABLE tbl;
22. MySQLの文字コード事情 Powered by Rabbit 2.1.9
テーブル Charset
テーブル属性だけ変更:
ALTER TABLE tbl CHARSET utf8mb4;
属性だけ変更しても既存のカラムは変更されない
全カラムとデータの変換:
ALTER TABLE tbl CONVERT TO CHARSET utf8mb4;
23. MySQLの文字コード事情 Powered by Rabbit 2.1.9
カラム Charset
テーブルCharsetが適切に設定されてれば指定する必
要はない
作成:
CREATE TABLE tbl (col VARCHAR(10) CHARSET
utf8mb4, ...);
確認:
SHOW CREATE TABLE tbl;
24. MySQLの文字コード事情 Powered by Rabbit 2.1.9
カラム Charset
変更:
ALTER TABLE tbl MODIFY col VARCHAR(10) CHARSET
utf8mb4;
変更するとカラム内のデータも変換される
25. MySQLの文字コード事情 Powered by Rabbit 2.1.9
クライアント Charset
クライアント内での文字列処理と
サーバーとの接続Charsetに使用される
指定方法はプログラム/言語に依存
mysql --default-character-set=utf8mb4
プログラムによっては my.cnf の [client] セクション
が有効
[client]
default-character-set = utf8mb4
26. MySQLの文字コード事情 Powered by Rabbit 2.1.9
クライアント Charset
mysqld との接続毎に異なる
mysql コマンドでOKでも他のアプリからはNGかもし
れない
何も指定しなければ latin1
27. MySQLの文字コード事情 Powered by Rabbit 2.1.9
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/ |
+--------------------------+----------------------------+
28. MySQLの文字コード事情 Powered by Rabbit 2.1.9
mysql コマンド
mysql コマンドのデフォルトCharsetは auto
システムロケール(LC_ALL, LC_CTYPE, LANG 環境変
数等)により値が決定
LANG=ja_JP.UTF-8 の場合は utf8 になる
utf8mb4 ではない
LANG=C の場合は latin1 になる
30. MySQLの文字コード事情 Powered by Rabbit 2.1.9
utf8接続から4バイト文字を参照
クライアントが扱えない文字は「?」になる
mysql> SELECT str FROM tbl;
+-------+
| str |
+-------+
| ?と? | ← '🍣と🍺'
| ?と? | ← '?と?'
+-------+
31. MySQLの文字コード事情 Powered by Rabbit 2.1.9
バイトコードを見れば違いがわかる
mysql> SELECT HEX(str) FROM tbl;
+------------------------+
| HEX(str) |
+------------------------+
| F09F8DA3E381A8F09F8DBA | ← '🍣と🍺'
| 3FE381A83F | ← '?と?'
+------------------------+
32. MySQLの文字コード事情 Powered by Rabbit 2.1.9
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 |
+-------------+------------------------+
33. MySQLの文字コード事情 Powered by Rabbit 2.1.9
sql_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
34. MySQLの文字コード事情 Powered by Rabbit 2.1.9
sql_mode
MySQL 5.7 からはデフォルト
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
35. MySQLの文字コード事情 Powered by Rabbit 2.1.9
🍣=🍺 問題
mysql> SELECT '🍣'='🍺';
+---------+
| '?'='?' |
+---------+
| 1 |
+---------+
38. MySQLの文字コード事情 Powered by Rabbit 2.1.9
Collation 一覧
mysql> SHOW COLLATION;
+--------------------------+----------+-----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+--------------------------+----------+-----+---------+----------+---------+
| big5_chinese_ci | big5 | 1 | Yes | Yes | 1 |
| big5_bin | big5 | 84 | | Yes | 1 |
| dec8_swedish_ci | dec8 | 3 | Yes | Yes | 1 |
| dec8_bin | dec8 | 69 | | Yes | 1 |
| cp850_general_ci | cp850 | 4 | Yes | Yes | 1 |
| cp850_bin | cp850 | 80 | | Yes | 1 |
| hp8_english_ci | hp8 | 6 | Yes | Yes | 1 |
| hp8_bin | hp8 | 72 | | Yes | 1 |
| koi8r_general_ci | koi8r | 7 | Yes | Yes | 1 |
| koi8r_bin | koi8r | 74 | | Yes | 1 |
| latin1_german1_ci | latin1 | 5 | | Yes | 1 |
| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 |
| latin1_danish_ci | latin1 | 15 | | Yes | 1 |
| latin1_german2_ci | latin1 | 31 | | Yes | 2 |
| latin1_bin | latin1 | 47 | | Yes | 1 |
| latin1_general_ci | latin1 | 48 | | Yes | 1 |
| latin1_general_cs | latin1 | 49 | | Yes | 1 |
39. MySQLの文字コード事情 Powered by Rabbit 2.1.9
utf8mb4 の Collation
utf8mb4_general_ci
utf8mb4_bin
utf8mb4_unicode_ci
utf8mb4_unicode_520_ci
utf8mb4_言語_ci
(utf8m4_japanese_ci は無い)
40. MySQLの文字コード事情 Powered by Rabbit 2.1.9
utf8mb4_general_ci
utf8mb4 Charset のデフォルト Collation
ASCII大文字小文字を区別しない(A=a)
絵文字を区別しない(🍣=🍺)
42. MySQLの文字コード事情 Powered by Rabbit 2.1.9
utf8mb4_unicode_ci
Unicode Collation Algorithm 4.0.0
http://www.unicode.org/reports/tr10/
http://dev.mysql.com/doc/refman/5.6/ja/charset-unicode-sets.html
ASCII大文字小文字を区別しない(A=a)
絵文字を区別しない(🍣=🍺)
ひらがな、カタカナ、濁点有無、全角、半角を区別し
ない
(は=ば=ぱ=ハ=バ=パ=ハ)
43. MySQLの文字コード事情 Powered by Rabbit 2.1.9
utf8mb4_unicode_520_ci
Unicode Collation Algorithm 5.2.0
ASCII大文字小文字を区別しない(A=a)
絵文字を区別する(🍣≠🍺)
ひらがな、カタカナ、濁点有無、全角、半角を区別し
ない
(は=ば=ぱ=ハ=バ=パ=ハ)
44. MySQLの文字コード事情 Powered by Rabbit 2.1.9
utf8mb4_*_ci
Collation A : a 🍣 : 🍺 は : ぱ : ば
general = = ≠
bin ≠ ≠ ≠
unicode = = =
unicode
_520
= ≠ =
45. MySQLの文字コード事情 Powered by Rabbit 2.1.9
まとめ
今から使うなら utf8mb4
サーバーとクライアントの両方で Charset を指定
sql_mode をちゃんと設定
Collation は適切に