sql >> Databáze >  >> RDS >> Mysql

Jaký je rozdíl mezi utf8_general_ci a utf8_unicode_ci?

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.



  1. Architektura SQL Server AlwaysOn ( Availability Group ) a instalace krok za krokem -3 kroky ručního selhání

  2. Psql seznam všech tabulek

  3. Prohlášení FORALL s vázanou doložkou INDICES-OF v databázi Oracle

  4. Jak zabránit útokům SQL Injection pomocí Secure