Pro lidi, kteří tuto otázku stále řeší v roce 2020 nebo později, existují novější možnosti, které mohou být lepší než obě z nich. Například utf8mb4_0900_ai_ci
.
Všechna tato řazení jsou pro kódování znaků UTF-8. Rozdíly jsou ve způsobu řazení a porovnávání textu.
_unicode_ci
a _general_ci
jsou dvě různé sady pravidel pro řazení a porovnávání textu podle toho, jak očekáváme. Novější verze MySQL zavádějí také nové sady pravidel, například _0900_ai_ci
pro ekvivalentní pravidla založená na Unicode 9.0 – a bez ekvivalentu _general_ci
varianta. Lidé, kteří toto čtou nyní, by pravděpodobně měli použít jedno z těchto novějších řazení namísto buď _unicode_ci
nebo _general_ci
. Popis těchto starších seřazení níže je uveden pouze pro zajímavost.
MySQL aktuálně přechází ze starší, chybné implementace UTF-8. Prozatím musíte používat utf8mb4
místo utf8
pro část kódování znaků, abyste zajistili, že získáte pevnou verzi. Chybná verze zůstává kvůli zpětné kompatibilitě, i když je zastaralá.
Hlavní rozdíly
-
utf8mb4_unicode_ci
je založeno na oficiálních pravidlech Unicode pro univerzální třídění a porovnávání, které přesně třídí v široké škále jazyků. -
utf8mb4_general_ci
je zjednodušený soubor pravidel třídění, jehož cílem je dělat to tak dobře, jak to jen jde, a přitom využívat mnoho zkratek navržených pro zvýšení rychlosti. Nedodržuje pravidla Unicode a v některých situacích bude mít za následek nežádoucí řazení nebo srovnání, například při použití určitých jazyků nebo znaků.Na moderních serverech bude toto zvýšení výkonu téměř zanedbatelné. Byl navržen v době, kdy servery měly nepatrný zlomek výkonu CPU dnešních počítačů.
Výhody utf8mb4_unicode_ci
přes utf8mb4_general_ci
utf8mb4_unicode_ci
, který používá pravidla Unicode pro třídění a porovnávání, využívá poměrně složitý algoritmus pro správné řazení v široké škále jazyků a při použití široké škály speciálních znaků. Tato pravidla musí brát v úvahu konvence specifické pro daný jazyk; ne každý třídí své znaky v tom, co bychom nazvali 'abecedním pořadím'.
Pokud jde o latinské (tj. „evropské“) jazyky, mezi řazením Unicode a zjednodušeným utf8mb4_general_ci
není velký rozdíl. řazení v MySQL, ale stále existuje několik rozdílů:
-
Například řazení Unicode třídí „ß“ jako „ss“ a „Œ“ jako „OE“, jak by lidé používající tyto znaky normálně chtěli, zatímco
utf8mb4_general_ci
seřadí je jako jednotlivé znaky (pravděpodobně jako „s“ a „e“). -
Některé znaky Unicode jsou definovány jako ignorovatelné, což znamená, že by se neměly započítávat do pořadí řazení a porovnání by se místo toho mělo přesunout na další znak.
utf8mb4_unicode_ci
zachází s nimi správně.
V jiných než latinských jazycích, jako jsou asijské jazyky nebo jazyky s různými abecedami, jich může být mnohem více rozdíly mezi tříděním Unicode a zjednodušeným utf8mb4_general_ci
třídění. Vhodnost utf8mb4_general_ci
bude silně záviset na použitém jazyce. Pro některé jazyky to bude docela nedostatečné.
Co byste měli použít?
Téměř jistě není důvod používat utf8mb4_general_ci
dále, protože jsme nechali bod, kdy je rychlost CPU dostatečně nízká na to, aby byl rozdíl ve výkonu důležitý. Vaše databáze bude téměř jistě omezena jinými úzkými hrdly, než je tato.
V minulosti někteří lidé doporučovali používat utf8mb4_general_ci
kromě případů, kdy přesné třídění bude dostatečně důležité, aby ospravedlnilo náklady na výkon. Dnes tyto náklady na výkon téměř zmizely a vývojáři berou internacionalizaci vážněji.
Je třeba argumentovat tím, že pokud je pro vás rychlost důležitější než přesnost, můžete také neprovádět žádné třídění. Je triviální udělat algoritmus rychlejší, pokud nepotřebujete, aby byl přesný. Takže utf8mb4_general_ci
je kompromis, který pravděpodobně není potřeba z důvodu rychlosti a pravděpodobně také není vhodný z důvodu přesnosti.
Další věc, kterou přidám, je, že i když víte, že vaše aplikace podporuje pouze anglický jazyk, možná se bude muset vypořádat se jmény lidí, která mohou často obsahovat znaky používané v jiných jazycích, ve kterých je stejně důležité správně třídit . Použití pravidel Unicode pro všechno pomáhá přidat klid na duši, že velmi chytří lidé s Unicode velmi tvrdě pracovali na tom, aby třídění fungovalo správně.
Co jednotlivé části znamenají
Za prvé, ci
je pro nerozlišují se malá a velká písmena třídění a porovnávání. To znamená, že je vhodný pro textová data a velikost písmen není důležitá. Další typy řazení jsou cs
(rozlišují se malá a velká písmena) pro textová data, kde jsou velká a malá písmena důležitá, a bin
, kde se kódování musí shodovat, bit po bitu, což je vhodné pro pole, která jsou skutečně kódovaná binární data (včetně například Base64). Třídění s rozlišováním malých a velkých písmen vede k podivným výsledkům a porovnávání s rozlišováním malých a velkých písmen může mít za následek duplicitní hodnoty, které se liší pouze velikostí písmen, takže řazení rozlišující malá a velká písmena u textových dat upadá v oblibu – pokud je pro vás velká a malá písmena důležitá, pak jinak ignorovatelnou interpunkci a tak dále je pravděpodobně také významné a vhodnější by mohlo být binární řazení.
Dále unicode
nebo general
odkazuje na specifická pravidla třídění a porovnávání - zejména na způsob, jakým je text normalizován nebo porovnáván. Existuje mnoho různých sad pravidel pro kódování znaků utf8mb4 s unicode
a general
jsou dva, které se snaží dobře fungovat ve všech možných jazycích, spíše než v jednom konkrétním. Rozdíly mezi těmito dvěma soubory pravidel jsou předmětem této odpovědi. Všimněte si, že unicode
používá pravidla z Unicode 4.0. Nejnovější verze MySQL přidávají sady pravidel unicode_520
pomocí pravidel z Unicode 5.2 a 0900
(vypuštění části "unicode_") pomocí pravidel z Unicode 9.0.
A nakonec utf8mb4
je samozřejmě interně používané kódování znaků. V této odpovědi mluvím pouze o kódování založeném na Unicode.