Jaka jest różnica między zestawami znaków utf8mb4 i utf8 w MySQL?

341

Jaka jest różnica między utf8mb4i utf8zestawami znaków w MySQL ?

Wiem już o kodowaniach ASCII , UTF-8 , UTF-16 i UTF-32 ; ale jestem ciekawy, jaka jest różnica między utf8mb4grupą kodowań a innymi typami kodowania zdefiniowanymi w MySQL Server .

Czy są jakieś szczególne korzyści / proponuje użycia utf8mb4zamiast utf8?

Mojtaba Rezaeian
źródło

Odpowiedzi:

391

UTF-8 jest kodowaniem o zmiennej długości. W przypadku UTF-8 oznacza to, że przechowywanie jednego punktu kodowego wymaga jednego do czterech bajtów. Jednak kodowanie MySQL o nazwie „utf8” (alias „utf8mb3”) przechowuje maksymalnie trzy bajty na punkt kodowy.

Zestaw znaków „utf8” / „utf8mb3” nie może przechowywać wszystkich punktów kodu Unicode: obsługuje tylko zakres od 0x000 do 0xFFFF, który nazywa się „ podstawową płaszczyzną wielojęzyczną ”. Zobacz także Porównanie kodowań Unicode .

Oto co mówi (poprzednia wersja tej samej strony) dokumentacja MySQL :

Zestaw znaków o nazwie utf8 [/ utf8mb3] wykorzystuje maksymalnie trzy bajty na znak i zawiera tylko znaki BMP. Począwszy od MySQL 5.5.3, zestaw znaków utf8mb4 używa maksymalnie czterech bajtów na znak i obsługuje znaki uzupełniające:

  • W przypadku znaku BMP utf8 [/ utf8mb3] i utf8mb4 mają identyczne cechy pamięci: te same wartości kodu, to samo kodowanie, ta sama długość.

  • W przypadku znaku uzupełniającego utf8 [/ utf8mb3] nie może w ogóle przechowywać znaku , podczas gdy utf8mb4 wymaga czterech bajtów do jego przechowywania. Ponieważ utf8 [/ utf8mb3] w ogóle nie może przechowywać znaku, nie masz żadnych dodatkowych znaków w kolumnach utf8 [/ utf8mb3] i nie musisz się martwić konwertowaniem znaków lub utratą danych podczas aktualizacji danych utf8 [/ utf8mb3] ze starszych wersji MySQL.

Jeśli więc chcesz, aby kolumna obsługiwała przechowywanie znaków leżących poza BMP (i zazwyczaj tego chcesz), takich jak emoji , użyj „utf8mb4”. Zobacz także Jakie są najczęściej używane znaki Unicode inne niż BMP? .

CodeCaster
źródło
10
Jedynymi przypadkami, które napotkałem (do tej pory), w których utf8mb4 był „wymagany”, są chińskie i emotikony. Istnieją niejasne alfabety, które tego potrzebują.
Rick James
10
Jest to również wymagane, jeśli używasz do przechowywania zaszyfrowanych haseł i danych w bazie danych. Trzymałem zaszyfrowane hasło w mysql w normalnym formacie utf8, co sprawiało mi wiele problemów z losowymi hasłami i bardzo trudno było je debugować, więc w końcu spróbowałem użyć kodowania base64 i tymczasowo usunąłem problem. Ale teraz znam przyczynę.
Mojtaba Rezaeian
38
@idealidea zaszyfrowane dane są binarne i nie należy przechowywać danych binarnych w kolumnie varchar. :)
CodeCaster,
8
@thomasrutter Wypróbuj (𡞰) znak, aby zapisać za pomocą UTF-8. :)
502_Geek
2
@MojtabaRezaeian w pewnym stopniu zależy to od algorytmu hasła - bcrypt2 wygeneruje ASCII.
Jasen
60

Zestaw utf8mb4znaków jest przydatny, ponieważ obecnie potrzebujemy wsparcia do przechowywania nie tylko znaków językowych, ale także symboli, nowo wprowadzonych emotikonów i tak dalej.

Miły artykuł na temat sposobu obsługi pełnego Unicode w bazach danych MySQL autorstwa Mathiasa Bynensa również może rzucić nieco światła na ten temat.

Jimmy Kane
źródło
11
MySQL 8.0 jest teraz domyślnie ustawiony na zestaw znaków utf8mb4. [ mysql.com/products/enterprise/techspec.html]
Ahmed Rezk
47

Na podstawie podręcznika MySQL 8.0 :

  • utf8mb4: Kodowanie UTF-8 zestawu znaków Unicode przy użyciu jednego do czterech bajtów na znak.

  • utf8mb3: Kodowanie UTF-8 zestawu znaków Unicode przy użyciu jednego do trzech bajtów na znak.

W MySQL utf8 jest obecnie alias, utf8mb3który jest przestarzały i zostanie usunięty w przyszłej wersji MySQL . W tym momencie utf8 stanie się odniesieniem do utf8mb4 .

Niezależnie od tego aliasu możesz świadomie ustawić sobie utf8mb4kodowanie.

Aby uzupełnić odpowiedź, chciałbym dodać komentarz @ WilliamEntriken poniżej (również zaczerpnięty z instrukcji):

Aby uniknąć dwuznaczności co do znaczenia utf8, rozważ utf8mb4wyraźne określenie odwołań do zestawu znaków zamiast utf8.

simhumileco
źródło