Dla osób, które nadal będą odpowiadać na to pytanie w 2020 r. lub później, istnieją nowsze opcje, które mogą być lepsze niż obydwa tych. Na przykład utf8mb4_0900_ai_ci
.
Wszystkie te zestawienia dotyczą kodowania znaków UTF-8. Różnice dotyczą sposobu sortowania i porównywania tekstu.
_unicode_ci
i _general_ci
to dwa różne zestawy reguł sortowania i porównywania tekstu zgodnie z naszymi oczekiwaniami. Nowsze wersje MySQL wprowadzają również nowe zestawy reguł, takie jak _0900_ai_ci
dla równoważnych reguł opartych na Unicode 9.0 - i bez równoważnego _general_ci
wariant. Osoby czytające to teraz powinny prawdopodobnie użyć jednego z tych nowszych zestawień zamiast _unicode_ci
lub _general_ci
. Poniższy opis tych starszych zestawień służy wyłącznie do zainteresowania.
MySQL odchodzi obecnie od starszej, wadliwej implementacji UTF-8. Na razie musisz użyć utf8mb4
zamiast utf8
dla części kodowania znaków, aby upewnić się, że otrzymujesz poprawioną wersję. Wadliwa wersja pozostaje kompatybilna z poprzednimi wersjami, chociaż jest przestarzała.
Kluczowe różnice
-
utf8mb4_unicode_ci
opiera się na oficjalnych zasadach Unicode dotyczących uniwersalnego sortowania i porównywania, które sortuje dokładnie w wielu językach. -
utf8mb4_general_ci
to uproszczony zestaw reguł sortowania, który ma na celu zrobienie tego jak najlepiej, przy jednoczesnym korzystaniu z wielu skrótów mających na celu zwiększenie szybkości. Nie jest zgodny z zasadami Unicode i spowoduje niepożądane sortowanie lub porównywanie w niektórych sytuacjach, na przykład podczas używania określonych języków lub znaków.Na nowoczesnych serwerach ten wzrost wydajności będzie prawie nieistotny. Został opracowany w czasie, gdy serwery miały niewielki ułamek wydajności procesora w dzisiejszych komputerach.
Zalety utf8mb4_unicode_ci
ponad utf8mb4_general_ci
utf8mb4_unicode_ci
, który wykorzystuje reguły Unicode do sortowania i porównywania, wykorzystuje dość złożony algorytm do poprawnego sortowania w wielu językach i przy użyciu szerokiej gamy znaków specjalnych. Zasady te muszą uwzględniać konwencje specyficzne dla języka; nie wszyscy sortują swoje postacie w tym, co nazwalibyśmy „porządkiem alfabetycznym”.
Jeśli chodzi o języki łacińskie (tj. „europejskie”), nie ma dużej różnicy między sortowaniem Unicode a uproszczonym utf8mb4_general_ci
sortowanie w MySQL, ale wciąż jest kilka różnic:
-
Na przykład sortowanie Unicode sortuje "ß" jak "ss" i "Œ" jak "OE", tak jak ludzie używający tych znaków normalnie by chcieli, podczas gdy
utf8mb4_general_ci
sortuje je jako pojedyncze znaki (przypuszczalnie jak odpowiednio "s" i "e"). -
Niektóre znaki Unicode są zdefiniowane jako możliwe do zignorowania, co oznacza, że nie powinny liczyć się do kolejności sortowania, a porównanie powinno przejść do następnego znaku.
utf8mb4_unicode_ci
radzi sobie z nimi właściwie.
W językach innych niż łacińskie, takich jak języki azjatyckie lub języki z różnymi alfabetami, może być dużo więcej różnice między sortowaniem Unicode a uproszczonym utf8mb4_general_ci
sortowanie. Przydatność utf8mb4_general_ci
będzie w dużym stopniu zależeć od używanego języka. W przypadku niektórych języków będzie to dość niewystarczające.
Czego powinieneś użyć?
Prawie na pewno nie ma powodu, aby używać utf8mb4_general_ci
już, ponieważ zostawiliśmy za sobą punkt, w którym prędkość procesora jest na tyle niska, że różnica w wydajności byłaby istotna. Twoja baza danych będzie prawie na pewno ograniczona przez inne wąskie gardła.
W przeszłości niektórzy polecali używanie utf8mb4_general_ci
z wyjątkiem sytuacji, gdy dokładne sortowanie miało być wystarczająco ważne, aby uzasadnić koszt wydajności. Dzisiaj ten koszt wydajności prawie zniknął, a programiści poważniej traktują internacjonalizację.
Można argumentować, że jeśli szybkość jest dla ciebie ważniejsza niż dokładność, równie dobrze możesz w ogóle nie robić żadnego sortowania. Przyspieszenie algorytmu jest trywialne, jeśli nie jest potrzebne, aby był dokładny. A więc utf8mb4_general_ci
to kompromis, który prawdopodobnie nie jest potrzebny ze względu na szybkość i prawdopodobnie nie jest odpowiedni ze względu na dokładność.
Jeszcze jedną rzeczą, którą dodam, jest to, że nawet jeśli wiesz, że Twoja aplikacja obsługuje tylko język angielski, może nadal wymagać radzenia sobie z nazwiskami osób, które często mogą zawierać znaki używane w innych językach, w których prawidłowe sortowanie jest równie ważne . Używanie reguł Unicode do wszystkiego pomaga zapewnić spokój ducha, że bardzo sprytni ludzie Unicode bardzo ciężko pracowali, aby sortowanie działało prawidłowo.
Co oznaczają części
Po pierwsze, ci
jest bez uwzględniania wielkości liter sortowanie i porównywanie. Oznacza to, że nadaje się do danych tekstowych, a wielkość liter nie jest ważna. Inne typy sortowania to cs
(wielkość liter ma znaczenie) dla danych tekstowych, gdzie wielkość liter jest ważna, oraz bin
, gdzie kodowanie musi być zgodne, bit po bicie, co jest odpowiednie dla pól, które są rzeczywiście zakodowanymi danymi binarnymi (w tym na przykład Base64). Sortowanie z uwzględnieniem wielkości liter prowadzi do dziwnych wyników, a porównywanie z uwzględnieniem wielkości liter może skutkować zduplikowanymi wartościami różniącymi się tylko wielkością liter, więc sortowanie z uwzględnieniem wielkości liter wypada z łask w przypadku danych tekstowych - jeśli wielkość liter jest dla Ciebie istotna, w przeciwnym razie można ignorować interpunkcję i tak dalej jest prawdopodobnie również znaczące, a porównanie binarne może być bardziej odpowiednie.
Następnie unicode
lub general
odnosi się do określonych reguł sortowania i porównywania – w szczególności sposobu normalizacji lub porównywania tekstu. Istnieje wiele różnych zestawów reguł dla kodowania znaków utf8mb4, z unicode
i general
to dwa, które starają się dobrze działać we wszystkich możliwych językach, a nie w jednym konkretnym. Przedmiotem tej odpowiedzi są różnice między tymi dwoma zestawami reguł. Zauważ, że unicode
używa reguł z Unicode 4.0. Najnowsze wersje MySQL dodają zestawy reguł unicode_520
używając reguł z Unicode 5.2 i 0900
(upuszczając część "unicode_") przy użyciu reguł z Unicode 9.0.
I na koniec utf8mb4
jest oczywiście kodowaniem znaków używanym wewnętrznie. W tej odpowiedzi mówię tylko o kodowaniu opartym na Unicode.