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

MySQLと令和 / MySQL to Reiwa

MySQLと令和 / MySQL to Reiwa

とみたまさひろ

December 18, 2019
Tweet

More Decks by とみたまさひろ

Other Decks in Technology

Transcript

  1. MySQLと令和
    MySQLと令和
    とみたまさひろ
    2019-12-18
    ニフクラエンジニアミートアップ
    #nifcloud_emup
    1

    View full-size slide

  2. 自己紹介
    自己紹介
    とみたまさひろ
    日本MySQLユーザ会 (文字化け担当)
    日本Rubyの会
    Oracle ACE Associate
    MySQL Parameters
    Ruby 2.7 アドベントカレンダー
    富士通クラウドテクノロジーズ
    @tmtms
    https://tmtms.hatenablog.com
    https://mysql-params.tmtms.net/mysqld/?vers=5.7.28,8.0.18
    https://qiita.com/advent-calendar/2019/ruby27
    2

    View full-size slide

  3. 令和元年もそろそろ終わりですね
    令和元年もそろそろ終わりですね
    3

    View full-size slide

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

    View full-size slide

  5. 令和になってからこの話をするのは5回目
    令和になってからこの話をするのは5回目
    くらいなのでどこかで見たことあるという
    くらいなのでどこかで見たことあるという
    人は生暖かい目で見てください
    人は生暖かい目で見てください
    5

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  9. 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 | ← ❗❗
    +-------+
    9

    View full-size slide


  10. 良かったですね
    10

    View full-size slide

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

    View full-size slide

  12. 異体字
    異体字

    「令
    令」と「
    」と「 」

    12

    View full-size slide

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

    View full-size slide

  14. 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 | ← ❗❗
    +-------+-------+
    14

    View full-size slide


  15. 良かったですね
    15

    View full-size slide

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

    View full-size slide

  17. 元号
    元号
    17

    View full-size slide

  18. 元号と言えば…
    元号と言えば…
    18

    View full-size slide

  19. 合字
    合字
    明治(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)
    19

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  25. 「令」 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]
    26

    View full-size slide

  26. その2
    その2
    異体字
    異体字

    「令
    令」と「
    」と「 」

    27

    View full-size slide

  27. 異体字セレクタ
    「令」 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
    28

    View full-size slide

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

    View full-size slide

  29. 平成=㍻
    平成=㍻
    平成(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]
    30

    View full-size slide

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

    View full-size slide

  31. 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. ]
    32

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  34. 「㋿」はUnicode 12.1.0 で追加
    http://unicode.org/versions/Unicode12.1.0/
    35

    View full-size slide

  35. 12.1 は「㋿」のためだけに 5/7 にリリース
    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.
    36

    View full-size slide

  36. MySQL の Unicode 12.1 対応はいつだろう…

    37

    View full-size slide

  37. 「令和」に関するあれこれは
    「令和」に関するあれこれは
    MySQL独自の変な挙動じゃなくてUnicode
    MySQL独自の変な挙動じゃなくてUnicode
    の規則だった!
    の規則だった!
    38

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  40. おまけ
    おまけ
    41

    View full-size slide

  41. 日本語Collation
    日本語Collation
    42

    View full-size slide

  42. 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 平仮名と片仮名は別の文字
    43

    View full-size slide

  43. JIS規則のCollation
    JIS規則のCollation
    44

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  47. 業界によってはうれしいかも
    業界によってはうれしいかも
    48

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  50. おわり
    おわり
    49

    View full-size slide