mysql 8.0 & unicode: why, what & how

26
Copyright © 2017 Oracle and/or its affiliates. All rights reserved. MySQL 8.0 & Unicode Why, what & how Bernt Marius Johnsen Senior Software QA Engineer

Upload: bernt-marius-johnsen

Post on 22-Jan-2018

1.378 views

Category:

Software


0 download

TRANSCRIPT

Page 1: MySQL 8.0 & Unicode: Why, what & how

Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

MySQL 8.0 & UnicodeWhy, what & how

Bernt Marius JohnsenSenior Software QA Engineer

Page 2: MySQL 8.0 & Unicode: Why, what & how

2Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

AgendaWhy Unicode

What is character set/collation etc.

How to migrate and some issues to consider

1

2

3

4

5

6

7

Page 3: MySQL 8.0 & Unicode: Why, what & how

3Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Why Unicode?

● The whole world is moving towards Unicode as digital devices is used by more and more people across all cultures all around the globe.– Approximate billion users of the six most used writing systems:

Latin1: ~5, Chinese: ~1.5, Arabic: ~0.7, Devanagari: ~0.5, Cyrillic: ~0.25, Bengali: ~0.22, Kana: ~0.12

● One driving force is Emojis– Smileys, hearts, roses etc, and all the stuff people are sending to each other when communicating

these days. )(���

– “Useful” example: Unicode character 0x1F574, MAN IN BUSINESS SUIT LEVITATING: �

1This is way more letters than just ASCII!

Page 4: MySQL 8.0 & Unicode: Why, what & how

4Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Why Unicode in a database?● You may use one character set for all your data, for all purposes.– E.g. if you make an application, utf8mb4 for a table with

names, it may be used by Russians, Chinese, Japanese etc.

– Even esoteric extinct writing systems are covered like e.g. the Phaistos disc (look it up...)

– But not Klingon, nor Tengwar �

Page 5: MySQL 8.0 & Unicode: Why, what & how

5Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

What is Unicode?● Unicode is a computing industry standard for the consistent encoding, representation, and handling of text expressed in most of the world's writing systems. (Wikipedia)

● ISO/IEC 10646● Unicode covers most existing and extinct writing systems known to man in one standard.

● The standard has allocated 17 planes, blocks of characters are allocated into the planes

● Three planes defined so far:● 0x0000-0xFFFF: Basic Multilingual Plane (BMP)● 0x10000-0x1FFFF: Supplementary Multilingual Plane (SMP)● 0x20000-0x2FFFF: Supplementary Ideographic Plane (SIP)

Page 6: MySQL 8.0 & Unicode: Why, what & how

6Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

What is a CHARACTER SET?● A character set is defined by:

– A repertoire of characters/graphemes

– A value given to each character/grapheme (codepoint)

– An encoding which defines the binary representation of the values

Page 7: MySQL 8.0 & Unicode: Why, what & how

7Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

What is Encoding?● The binary representation of a character. Unicode defines 3 encodings:– UTF-8 (1-4 bytes per character)

– UTF-16 (2 or 4 bytes per character)

– UTF32 (4 bytes per character)

Page 8: MySQL 8.0 & Unicode: Why, what & how

8Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Character set examplesCharacter Character set Value Encoding Encoded as

A ASCIIISO-8859-1 (Latin-1)Unicode

41410041

1:11:1UTF-8UTF16

4141410041

Ä ISO-8859-1 (Latin-1)Unicode

C400C4

1:1UTF-8UTF16

C4C38400C4

д KOI8-RISO-8859-5Unicode

C4D40434

1:11:1UTF-8UTF-16

C4D4D0B40434

人 GB-18030Unicode

Big5JIS X 0208 (SJIS)

C8CB4EBA

A448906C

1:1UTF-8UTF-161:11:1

C8CBE4BABA4EBAA448906C

� Unicode

GB-18030

1F574

9439EE36

UTF8UTF-161:1

F09F95B4D83DDD749439EE36

Page 9: MySQL 8.0 & Unicode: Why, what & how

9Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

What is collation● Collation is the assembly of written information into a standard order

(Wikipedia)

● Collation may consider

– Case (e.g 'A' vs. 'a')

– Accents (e.g. 'E' vs. 'É')

– Locale-specific rules (e.g. 'A' vs. 'Å' vs. 'AA' in Danish and Norwegian)

– Numeric characters (e.g. '2' vs. ' ')ⅱ

– Punctuation (e.g. 'blackbird' vs. 'black-bird')

– Etc.●

Page 10: MySQL 8.0 & Unicode: Why, what & how

10Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

What is a COLLATION in (My)SQL?● In MySQL, a COLLATION is a set of rules for a given character set which

defines an order and affects:

– ORDER BY

– LIKE

– Primary keys and indexes

– Unique constraints

– Comparison operators

– Some string functions● All strings in MySQL have a character set and a collation

Page 11: MySQL 8.0 & Unicode: Why, what & how

11Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Character sets in MySQL+­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­+

| Charset  | Description                     | Default collation   | Maxlen |

+­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­+­­­­­­­­+

| ascii    | US ASCII                        | ascii_general_ci    |      1 |

| latin1   | cp1252 West European            | latin1_swedish_ci   |      1 |

| utf8     | UTF­8 Unicode                   | utf8_general_ci     |      3 |

| utf8mb4  | UTF­8 Unicode                   | utf8mb4_0900_ai_ci  |      4 |

Get all by typing:

mysql> show character set;

The rest of them are:

armscii8, big5, binary, cp1250, cp1251, cp1256, cp1257, cp850, cp852, cp866, cp932, dec8, eucjpms, euckr, gb18030, gb2312, gbk, geostd8, greek, hebrew, hp8, keybcs2, koi8r, koi8u, latin2, latin5, latin7, macce, macroman, sjis, swe7, tis620, ucs2, ujis, utf16, utf16le, utf32

Page 12: MySQL 8.0 & Unicode: Why, what & how

12Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

What's new in MySQL 8.0● utf8mb4 will be the default character set for 8.0● utf8mb4_0900_ai_ci is the default collation of utf8mb4

● A lot of new collations based on Unicode v. 9.0.0 – UCA (Unicode Collation Algorithm)

– DUCET (Default Unicode Collation Entry Table)

– CLDR v.30 (Common Locale Data Repository)

Page 13: MySQL 8.0 & Unicode: Why, what & how

13Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

MySQL 8.0 collation name scheme● <charset>[_<language> [_<variant>]]_<unicodeversion>(_<attribute>)+

– <charset> = utf8mb4

– <language>, an ISO 639-1 language code (or ISO 639-2 if needed)

– <variant>, a variant to the standard collation for the language. Per today: utf8mb4_de_pb_0900_* and utf8mb4_es_trad_0900_*.

– <unicodeversion> = 0900

– <attribute>: accent sensitivity (ai, as), case sensitivity (ci, cs) and possible future ones.

● Special collations:– Default collation (not language specific): utf8mb4_0900_ai_ci

● may be used for German dictionary order, English, French1, Irish Gaelic, Indonesian, Italian, Luxembourgian, Malay, Dutch, Portuguese, Swahili and Zulu

– Codepoint order: utf8mb4_bin1) Canadian French may not use utf8mb4_0900_as_cs collations due to differences to standard accent order.

Page 14: MySQL 8.0 & Unicode: Why, what & how

14Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Why not ...● Fix utf8mb4_general_ci instead of introducing utf8mb4_0900_ai_ci or fix utf8mb4_german2_ci instead of introducing utf8mb4_de_pb_0900_ai_ci?– Because that might break existing applications using the old collations (The

most serious issue for large databases: Indexes would have to be rebuilt). Policy: Collations don't change!

● Have a simpler name scheme?– Because we prepare for

● More languages● New Unicode versions (Unicode 10.0.0 is expected in 2018)

– ISO-639-1/ISO-639-2 language codes are well defined

Page 15: MySQL 8.0 & Unicode: Why, what & how

15Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

How to migrate?● When migrating from 5.7 tables:

– Just convert the table:ALTER TABLE foo CONVERT TO CHARACTER SET utf8mb4;● This will change the default character set of the table (so that future

new columns get utf8mb4) and the character set of all applicable columns.

● In principle, all character data in MySQL may be converted to utf8mb4 without loss of data.

That was easy ..... is that all to it ... ?

Page 16: MySQL 8.0 & Unicode: Why, what & how

16Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

… not quite … column by column● If you have more complex tables with different character sets:

– Change the default character set of the table:ALTER TABLE foo DEFAULT CHARACTER SET utf8mb4;

– Modify all relevant relevant columns:ALTER TABLE foo MODIFY bar VARCHAR(100) CHARACTER SET utf8mb4;

Generally we recommend doing it column by column.– ALTER TABLE … CONVERT … will e.g. change TEXT to MEDIUMTEXT

when you convert from latin1 to utf8mb4 and that won't necessarily be what you want.

Page 17: MySQL 8.0 & Unicode: Why, what & how

17Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

… not quite … the schema too● A schema (aka. database) in MySQL has a default character set which will be the default character set of new tables in the schema– mysql> show create schema bar;+­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+| Database | Create Database                                                |+­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+| bar      | CREATE DATABASE `bar` /*!40100 DEFAULT CHARACTER SET latin1 */ |+­­­­­­­­­­+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+1 row in set (0.00 sec)

● Change the default character set of the schema(database):ALTER SCHEMA bar DEFAULT CHARACTER SET utf8mb4;

Page 18: MySQL 8.0 & Unicode: Why, what & how

18Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

… not quite … collation differencesCollations are not equal, so converting from one collation to another may break UNIQUE constraints (e.g PRIMARY KEY).● Default collation:

– latin1_swedish_ci vs. utf8mb4_0900_ai_ciE.g. 'a'='å' is false in the first, but true in the other.

– Possible solution: Stick to Swedish/Danish/Norwegian depending on your application.:ALTER TABLE foo CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_sv_0900_ai_ci;

– Generally, if you don't care about case insensitivity (just got it by default), utf8mb4_0900_as_cs should be safe.

● There's an huge number of possibilities depending on your data and the collations used, partly because pre MySQL 8.0 collations where not complete (and in some cases not correct).

Page 19: MySQL 8.0 & Unicode: Why, what & how

19Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

… not quite … index and key issues● If you change the collation of a column, indexes on that column will be regenerated.– This takes time for large data, and the table is locked during that time.

– And the conversion may fail due to changed space consumption.

● Max key length is 3072 bytes1, which implies that max length of a utf8mb4 varchar column which is also a key is 768 characters (Worst case scenario: 4 bytes per character).– mysql> create table foo (v varchar(1000) character set latin1 primary key);Query OK, 0 rows affected (0.01 sec)mysql> alter table foo modify v varchar(1000) character set utf8mb4;ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

1For default InnoDB row format and default innodb_page_size in MySQL 8.0. See the documentation for details.

Page 20: MySQL 8.0 & Unicode: Why, what & how

20Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Space consumption● utf8mb4 use

– 1 byte for ASCII characters (0x00-0x7F),

– 2 bytes for most alphabets/abjads (0x80-0x7FF),

– 3 bytes for Indic scripts, Hangul, Kana, the most used CJK Ideographs (0x800-0xFFFF),

– 4 bytes for the rest: Archaic scripts, Emojis, Rarely used CJK extensions etc. (0x10000-)

Page 21: MySQL 8.0 & Unicode: Why, what & how

21Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Speed issues● Operations on multibyte character sets inherently slower than singlebyte character sets (e.g. latin1 vs. utf8mb4)

● We are working on a lot of code improvements.– Expect a performance degradation in the order of 10-

20% for sorting when you migrate from e.g latin1 to utf8mb4, depending on your data of course.

Page 22: MySQL 8.0 & Unicode: Why, what & how

22Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

⚠ 文字化け (Mojibake) … or you what you see is not what you get...mysql> create table foo(v varchar(10) character set latin1);

mysql> insert into foo values('å');

mysql> set names latin1;

mysql> insert into foo values('å');

mysql> set names utf8;

mysql> select * from foo;

+­­­­­­+

| v    |

+­­­­­­+

| å    |

| Ã¥   |

+­­­­­­+

2 rows in set (0.00 sec)

mysql> select hex(v) from foo;+­­­­­­­­+| hex(v) |+­­­­­­­­+| E5     || C3A5   |+­­­­­­­­+2 rows in set (0.00 sec)

Page 23: MySQL 8.0 & Unicode: Why, what & how

23Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Truly usable for global purposes.....

Page 24: MySQL 8.0 & Unicode: Why, what & how

24Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Q&A

�U+1F634

Page 25: MySQL 8.0 & Unicode: Why, what & how

25Copyright © 2017 Oracle and/or its affiliates. All rights reserved.

Safe Harbor Statement

The preceding is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.

Page 26: MySQL 8.0 & Unicode: Why, what & how