Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MySQLと令和 / MySQL with Reiwa

MySQLと令和 / MySQL with Reiwa

とみたまさひろ

August 10, 2019
Tweet

More Decks by とみたまさひろ

Other Decks in Technology

Transcript

  1. MySQLと令和
    MySQLと令和
    とみたまさひろ
    2019-08-10
    NSEG
    1

    View full-size slide

  2. 自己紹介
    自己紹介
    とみたまさひろ
    プログラマー?

    富士通クラウドテクノロジーズ
    日本MySQLユーザ会
    得意技: Ruby, 文字化け
    @tmtms
    https://tmtm.github.io/mysql-params/
    https://tmtm.github.io/postfix-params/
    2

    View full-size slide

  3. ㊗令和元年

    ㊗令和元年

    3

    View full-size slide

  4. 今日は「令和」の話をします
    今日は「令和」の話をします
    4

    View full-size slide

  5. その1
    その1
    「令和」と言えば…
    「令和」と言えば…
    5

    View full-size slide

  6. 似てるけど違う文字
    似てるけど違う文字
    「令」と「令」
    「令」と「令」
    6

    View full-size slide

  7. 同じに見えるけど別の文字
    同じに見えるけど別の文字
    「令」 U+4EE4 CJK UNIFIED IDEOGRAPH
    「令」 U+F9A8 CJK COMPATIBILITY IDEOGRAPH
    困る!
    7

    View full-size slide

  8. MySQLでは
    MySQLでは
    一致
    mysql> set @a='令和', @b='令和';
    mysql> select @a, @b, hex(@a), hex(@b);
    +--------+--------+--------------+--------------+
    | @a | @b | hex(@a) | hex(@b) |
    +--------+--------+--------------+--------------+
    | 令和 | 令和 | E4BBA4E5928C | EFA6A8E5928C |
    +--------+--------+--------------+--------------+
    mysql> select @a=@b;
    +-------+
    | @a=@b |
    +-------+
    | 1 | ← ❗❗
    +-------+
    8

    View full-size slide

  9. その2
    その2
    「令和」と言えば…
    「令和」と言えば…
    10

    View full-size slide

  10. 異体字
    異体字

    「令
    令」と「
    」と「 」

    11

    View full-size slide

  11. 違う字形だけど同じ文字
    違う字形だけど同じ文字
    異体字セレクタ
    「令」 U+4EE4
    「令」 U+4EE4 U+E0101
    「 」 U+4EE4 U+E0102
    困る!
    12

    View full-size slide

  12. MySQLでは
    MySQLでは
    ※都合により同じ字体に見えてます
    一致
    mysql> set @a='令和', @b='令 和', @c='令 和';
    mysql> select hex(@a), hex(@b), hex(@c)\G
    *************************** 1. row ***************************
    hex(@a): E4BBA4E5928C
    hex(@b): E4BBA4F3A08481E5928C
    hex(@c): E4BBA4F3A08482E5928C
    mysql> select @a=@b, @b=@c;
    +-------+-------+
    | @a=@b | @b=@c |
    +-------+-------+
    | 1 | 1 | ← ❗❗
    +-------+-------+
    13

    View full-size slide

  13. その3
    その3
    「令和」と言えば…
    「令和」と言えば…
    15

    View full-size slide

  14. 元号
    元号
    16

    View full-size slide

  15. 元号と言えば…
    元号と言えば…
    17

    View full-size slide

  16. 合字
    合字
    明治(U+660E U+6CBB) ㍾(U+337E)
    ⼤正(U+5927 U+6B63) ㍽(U+337D)
    昭和(U+662D U+548C) ㍼(U+337C)
    平成(U+5E73 U+6210) ㍻(U+337B)
    令和(U+4EE4 U+548C) ㋿(U+32FF)
    18

    View full-size slide

  17. MySQLでは
    MySQLでは
    mysql> select '明治'='㍾', '大正'='㍽', '昭和'='㍼',
    -> '平成'='㍻', '令和'='㋿'\G
    *************************** 1. row ***************************
    '明治'='㍾': 1 ← 一致❗
    '大正'='㍽': 1 ← 一致❗
    '昭和'='㍼': 1 ← 一致❗
    '平成'='㍻': 1 ← 一致❗
    '令和'='㋿': 0 ← 不一致❗
    19

    View full-size slide

  18. なにが起きてるのか?
    なにが起きてるのか?
    21

    View full-size slide

  19. MySQL は Unicode 9.0.0 準拠
    MySQL は Unicode 9.0.0 準拠
    22

    View full-size slide

  20. Unicodeの照合順序
    Unicodeの照合順序
    Unicode Collation Algorithm (UCA)
    Default Unicode Collation Element Table (DUCET)
    文字毎にWeightという値が定義されている
    Weightが等しいなら等しい文字
    https://unicode.org/reports/tr10/tr10-34.html
    https://www.unicode.org/Public/UCA/9.0.0/allkeys.txt
    23

    View full-size slide

  21. その1
    その1
    似てるけど違う文字
    似てるけど違う文字
    「令」と「令」
    「令」と「令」
    24

    View full-size slide

  22. 「令」 U+4EE4 CJK UNIFIED IDEOGRAPH
    DUCETには無いけど計算で求まる
    「令」 U+F9A8 CJK COMPATIBILITY IDEOGRAPH
    DUCETにある
    Weightが一致するから等しい
    [.FB40.0020.0002][.(CP | 0x8000).0000.0000]
    → [.FB40.0020.0002][.CEE4.0000.0000]
    F9A8 ; [.FB40.0020.0002][.CEE4.0000.0000]
    25

    View full-size slide

  23. その2
    その2
    異体字
    異体字

    「令
    令」と「
    」と「 」

    26

    View full-size slide

  24. 異体字セレクタ
    「令」 U+4EE4
    「令」 U+4EE4 U+E0101
    「 」 U+4EE4 U+E0102
    異体字セレクタはDUCETにある
    UCAではすべてゼロの文字は無視
    E0101 ; [.0000.0000.0000] # VARIATION SELECTOR-18
    E0102 ; [.0000.0000.0000] # VARIATION SELECTOR-19
    27

    View full-size slide

  25. その3
    その3
    合字
    合字
    ㍾ / ㍽ / ㍼ / ㍻ / ㋿
    28

    View full-size slide

  26. 平成=㍻
    平成=㍻
    平成(U+5E73 U+6210): ㍻(U+337B)
    ちょっと違う…

    平成 [.FB40.0020.0002][.DE73.0000.0000][.FB40.0020.0002][.E210.0000.0000]
    ㍻ [.FB40.0020.001C][.DE73.0000.0000][.FB40.0020.001C][.E210.0000.0000]
    29

    View full-size slide

  27. utf8mb4_0900_ai_ci
    utf8mb4_0900_ai_ci
    MySQLのデフォルトのCollation
    要素 意味
    utf8mb4 4バイトUTF-8
    0900 Unicode 9.0.0
    ai アクセントの違いを無視
    ci 大文字小文字の違いを無視
    ciの場合はWeightの3番目を無視
    30

    View full-size slide

  28. ciの場合はWeightの3番目を無視
    3番目を無視すると
    一致
    平成 [.FB40.0020.0002][.DE73.0000.0000][.FB40.0020.0002][.E210.0000.0000]
    ㍻ [.FB40.0020.001C][.DE73.0000.0000][.FB40.0020.001C][.E210.0000.0000]
    平成 [.FB40.0020. ][.DE73.0000. ][.FB40.0020. ][.E210.0000. ]
    ㍻ [.FB40.0020. ][.DE73.0000. ][.FB40.0020. ][.E210.0000. ]
    31

    View full-size slide

  29. 令和≠㋿
    令和≠㋿
    そもそも「㋿」がDUCETに無い!
    32

    View full-size slide

  30. 「㋿」はUnicode 9.0.0 に無い!
    33

    View full-size slide

  31. 「㋿」はUnicode 12.1.0 で追加
    12.1 は「㋿」のためだけに 5/7 にリリース
    http://unicode.org/versions/Unicode12.1.0/
    Unicode 12.1 adds exactly one character, for a total of 137,929
    characters.
    The new character added to Version 12.1 is:
    U+32FF SQUARE ERA NAME REIWA
    Version 12.1 adds that single character to enable software to be
    rapidly updated to support the new Japanese era name in calendrical
    systems and date formatting. The new Japanese era name was officially
    announced on April 1, 2019, and is effective as of May 1, 2019.
    34

    View full-size slide

  32. MySQL独自の変な挙動じゃなくて
    MySQL独自の変な挙動じゃなくて
    Unicodeの規則だった!
    Unicodeの規則だった!
    35

    View full-size slide

  33. Unicode規則にちゃんと従ってる
    Unicode規則にちゃんと従ってる
    MySQLえらい!
    MySQLえらい!
    36

    View full-size slide

  34. Collationについて学べる「令和」
    Collationについて学べる「令和」
    すごい!
    すごい!
    37

    View full-size slide

  35. おまけ
    おまけ
    38

    View full-size slide

  36. 日本語Collation
    日本語Collation
    39

    View full-size slide

  37. utf8mb4_
    utf8mb4_ja
    ja_0900_as_cs
    _0900_as_cs
    utf8mb4_
    utf8mb4_ja
    ja_0900_as_cs_
    _0900_as_cs_ks
    ks
    要素 意味
    utf8mb4 4バイトUTF-8
    ja 言語
    0900 Unicode 9.0.0
    as アクセント違いは別の文字
    cs 大文字小文字は別の文字
    ks 平仮名と片仮名は別の文字
    40

    View full-size slide

  38. JIS規則のCollation
    JIS規則のCollation
    41

    View full-size slide

  39. 比較 ai_ci as_ci as_cs ja as_cs ja as_cs_ks bin
    A=a ◯ ◯ × × × ×
    A=A ◯ ◯ × ◯ ◯ ×
    A=a ◯ ◯ × × × ×
    あ=ぁ ◯ ◯ × × × ×
    あ=ア ◯ ◯ × ◯ × ×
    は=ば=ぱ ◯ × × × × ×
    1=① ◯ ◯ × × × ×
    令=令 ◯ ◯ ◯ × × ×
    令= ◯ ◯ ◯ ◯ ◯ ×
    平成=㍻ ◯ ◯ × × × ×
    42

    View full-size slide

  40. ソート順もJIS
    ソート順もJIS
    mysql> select c,hex(c) from t order by c;
    +------+--------+
    | c | hex(c) |
    +------+--------+
    | 亜 | E4BA9C |
    | 伊 | E4BC8A |
    | 宇 | E5AE87 |
    | 栄 | E6A084 |
    | 奥 | E5A5A5 |
    +------+--------+
    43

    View full-size slide

  41. 長音記号のソート順は前の文字の母音と同じ
    長音記号のソート順は前の文字の母音と同じ
    mysql> select c from t2 order by c;
    +--------+
    | c |
    +--------+
    | かー |
    | かあ |
    | かい |
    | きあ |
    | きー |
    | きい |
    | くあ |
    | くい |
    | くー |
    +--------+
    44

    View full-size slide

  42. 業界によってはうれしいかも
    業界によってはうれしいかも
    45

    View full-size slide

  43. 業界によってはうれしいかも
    業界によってはうれしいかも
    ちょっとやりすぎ感?
    ちょっとやりすぎ感?
    45

    View full-size slide

  44. 業界によってはうれしいかも
    業界によってはうれしいかも
    ちょっとやりすぎ感?
    ちょっとやりすぎ感?
    文句はJISに
    文句はJISに
    45

    View full-size slide

  45. おまけ2
    おまけ2
    46

    View full-size slide

  46. utf8mb4_0900_bin
    utf8mb4_0900_bin
    MySQL 8.0.17 から登場
    47

    View full-size slide

  47. CollationのPAD属性
    CollationのPAD属性
    8.0 から追加
    PAD SPACE - 末尾空白文字の有無を無視する
    5.7までの振る舞い
    NO PAD - 末尾空白文字の有無を無視しない
    8.0からの新しいCollation
    utf8mb4_*0900_*
    48

    View full-size slide

  48. PAD SPACE と NO PAD
    PAD SPACE と NO PAD
    mysql> set names utf8mb4 collate utf8mb4_unicode_520_ci;
    mysql> select 'a' = 'a ';
    +--------------+
    | 'a' = 'a ' |
    +--------------+
    | 1 |
    +--------------+
    mysql> set names utf8mb4 collate utf8mb4_0900_ai_ci;
    mysql> select 'a' = 'a ';
    +--------------+
    | 'a' = 'a ' |
    +--------------+
    | 0 |
    +--------------+
    49

    View full-size slide

  49. utf8mb4_0900_bin
    utf8mb4_0900_bin
    utf8mb4_bin にも NO PAD バージョンが欲しい
    互換のために utf8mb4_bin は変更できない
    utf8mb4_0900_bin 新設
    50

    View full-size slide

  50. utf8mb4_bin と utf8mb4_0900_bin
    utf8mb4_bin と utf8mb4_0900_bin
    mysql> set names utf8mb4 collate utf8mb4_bin;
    mysql> select 'a' = 'a ';
    +--------------+
    | 'a' = 'a ' |
    +--------------+
    | 1 |
    +--------------+
    mysql> set names utf8mb4 collate utf8mb4_0900_bin;
    mysql> select 'a' = 'a ';
    +--------------+
    | 'a' = 'a ' |
    +--------------+
    | 0 |
    +--------------+
    51

    View full-size slide

  51. 名前がイマイチな気がする

    名前がイマイチな気がする

    0900 は Unicode 9.0.0 準拠のCollationという意味
    utf8mb4_0900_bin は Unicode 準拠じゃない
    NO PADなCollationは0900だけだからこうなった?
    それにしてもなー
    52

    View full-size slide

  52. まとめ
    まとめ
    53

    View full-size slide

  53. まとめ
    まとめ
    適切なCollationを選ぼう!
    適切なCollationを選ぼう!
    53

    View full-size slide

  54. まとめ
    まとめ
    適切なCollationを選ぼう!
    適切なCollationを選ぼう!
    Collation多すぎ?
    Collation多すぎ?
    53

    View full-size slide

  55. まとめ
    まとめ
    適切なCollationを選ぼう!
    適切なCollationを選ぼう!
    Collation多すぎ?
    Collation多すぎ?
    実は全ての文字を区別できる
    実は全ての文字を区別できる
    utf8mb4_0900_bin でよかったり?
    utf8mb4_0900_bin でよかったり?
    たぶん速いし
    たぶん速いし
    53

    View full-size slide