sql >> Database teknologi >  >> RDS >> Mysql

Hvad er forskellen mellem utf8_general_ci og utf8_unicode_ci?

For de mennesker, der stadig kommer frem til dette spørgsmål i 2020 eller senere, er der nyere muligheder, der kan være bedre end begge af disse. For eksempel utf8mb4_0900_ai_ci .

Alle disse sorteringer er til UTF-8 tegnkodning. Forskellene er, hvordan tekst sorteres og sammenlignes.

_unicode_ci og _general_ci er to forskellige sæt regler for sortering og sammenligning af tekst efter den måde, vi forventer. Nyere versioner af MySQL introducerer også nye sæt regler, såsom _0900_ai_ci for tilsvarende regler baseret på Unicode 9.0 - og uden tilsvarende _general_ci variant. Folk, der læser dette nu, bør sandsynligvis bruge en af ​​disse nyere samlinger i stedet for enten _unicode_ci eller _general_ci . Beskrivelsen af ​​disse ældre samlinger nedenfor er kun givet til interesse.

MySQL er i øjeblikket på vej væk fra en ældre, mangelfuld UTF-8-implementering. Indtil videre skal du bruge utf8mb4 i stedet for utf8 for tegnkodningsdelen for at sikre, at du får den faste version. Den fejlbehæftede version forbliver for bagudkompatibilitet, selvom den er ved at blive forældet.

Vigtige forskelle

  • utf8mb4_unicode_ci er baseret på de officielle Unicode-regler for universel sortering og sammenligning, som sorterer nøjagtigt på en lang række sprog.

  • utf8mb4_general_ci er et forenklet sæt af sorteringsregler, som har til formål at gøre det så godt, som det kan, og samtidig tage mange genveje designet til at forbedre hastigheden. Det følger ikke Unicode-reglerne og vil resultere i uønsket sortering eller sammenligning i nogle situationer, såsom ved brug af bestemte sprog eller tegn.

    På moderne servere vil dette præstationsboost være næsten ubetydeligt. Det blev udtænkt i en tid, hvor servere havde en lille brøkdel af CPU-ydelsen på nutidens computere.

Fordele ved utf8mb4_unicode_ci over utf8mb4_general_ci

utf8mb4_unicode_ci , som bruger Unicode-reglerne til sortering og sammenligning, anvender en ret kompleks algoritme til korrekt sortering på en lang række sprog og ved brug af en lang række specialtegn. Disse regler skal tage hensyn til sprogspecifikke konventioner; ikke alle sorterer deres karakterer i, hvad vi ville kalde 'alfabetisk rækkefølge'.

Hvad angår latinske (dvs. "europæiske") sprog, er der ikke den store forskel mellem Unicode-sortering og den forenklede utf8mb4_general_ci sortering i MySQL, men der er stadig et par forskelle:

  • For eksempel sorterer Unicode-sorteringen "ß" som "ss" og "Œ" som "OE", som folk, der bruger disse tegn normalt vil have, mens utf8mb4_general_ci sorterer dem som enkelte tegn (formodentlig som henholdsvis "s" og "e").

  • Nogle Unicode-tegn er defineret som ignorable, hvilket betyder, at de ikke skal tælle med i sorteringsrækkefølgen, og sammenligningen skal gå videre til næste tegn i stedet. utf8mb4_unicode_ci håndterer disse korrekt.

På ikke-latinske sprog, såsom asiatiske sprog eller sprog med forskellige alfabeter, kan der være meget mere forskelle mellem Unicode-sortering og den forenklede utf8mb4_general_ci sortering. Egnetheden af ​​utf8mb4_general_ci vil i høj grad afhænge af det anvendte sprog. For nogle sprog vil det være ret utilstrækkeligt.

Hvad skal du bruge?

Der er næsten helt sikkert ingen grund til at bruge utf8mb4_general_ci længere, da vi har efterladt det punkt, hvor CPU-hastigheden er lav nok til, at ydelsesforskellen ville være vigtig. Din database vil næsten helt sikkert være begrænset af andre flaskehalse end dette.

Tidligere anbefalede nogle mennesker at bruge utf8mb4_general_ci undtagen når nøjagtig sortering ville være vigtig nok til at retfærdiggøre præstationsomkostningerne. I dag er disse præstationsomkostninger næsten forsvundet, og udviklere behandler internationalisering mere seriøst.

Der er et argument at fremføre, at hvis hastighed er vigtigere for dig end nøjagtighed, kan du lige så godt ikke foretage nogen sortering overhovedet. Det er trivielt at lave en algoritme hurtigere, hvis du ikke har brug for, at den er nøjagtig. Så utf8mb4_general_ci er et kompromis, der sandsynligvis ikke er nødvendigt af hastighedsmæssige årsager og sandsynligvis heller ikke egnet af hensyn til nøjagtigheden.

En anden ting, jeg vil tilføje, er, at selvom du ved, at din ansøgning kun understøtter det engelske sprog, kan den stadig være nødt til at håndtere folks navne, som ofte kan indeholde tegn, der bruges på andre sprog, hvor det er lige så vigtigt at sortere korrekt. . At bruge Unicode-reglerne til alting hjælper med at give ro i sindet, at de meget smarte Unicode-folk har arbejdet meget hårdt for at få sortering til at fungere korrekt.

Hvad delene betyder

For det første ci er uafhængig af store og små bogstaver sortering og sammenligning. Det betyder, at det er egnet til tekstdata, og store og små bogstaver er ikke vigtigt. De andre sorteringstyper er cs (forskel på store og små bogstaver) for tekstdata, hvor store og små bogstaver er vigtige, og bin , for hvor kodningen skal matche, bit for bit, hvilket er velegnet til felter, som er virkelig kodede binære data (inklusive f.eks. Base64). Skift og små bogstaver sortering fører til nogle mærkelige resultater, og sammenligning af store og små bogstaver kan resultere i, at duplikerede værdier kun adskiller sig i store og små bogstaver, så store og små bogstaver falder ude af fordel for tekstdata - hvis store og små bogstaver er vigtige for dig, så ellers ignorerbar tegnsætning og så videre er sandsynligvis også signifikant, og en binær sammenstilling kan være mere passende.

Dernæst unicode eller general henviser til de specifikke sorterings- og sammenligningsregler - især måden tekst normaliseres eller sammenlignes på. Der er mange forskellige sæt regler for utf8mb4 tegnkodning med unicode og general at være to, der forsøger at fungere godt på alle mulige sprog frem for ét specifikt. Forskellene mellem disse to sæt regler er emnet for dette svar. Bemærk, at unicode bruger regler fra Unicode 4.0. Nylige versioner af MySQL tilføjer regelsættene unicode_520 ved hjælp af regler fra Unicode 5.2 og 0900 (slip "unicode_"-delen) ved hjælp af regler fra Unicode 9.0.

Og til sidst, utf8mb4 er naturligvis tegnkodningen, der bruges internt. I dette svar taler jeg kun om Unicode-baserede kodninger.



  1. Tæl antallet af forekomster af en streng i et VARCHAR-felt?

  2. SQL Server 2016:Opret en lagret procedure

  3. Parameter Sniffing, Embedding og RECOMPILE-indstillingerne

  4. Sådan får du en liste over datoer mellem to datoer i mysql select-forespørgsel