Godt nyt på udvikler-fronten: Tricky UTF-8-faldgrube bliver fikset i MySQL

MySQL er en populær database, men håndteringen af tegnsæt kan være tricky.

Tegnsæt er en evig kilde til for tidlige grå hår hos udviklere, men med Unicode og UTF-8 burde det da efterhånden være nogenlunde til at gennemskue? Ikke helt, men vi nærmer os.

En udvikler hos konsulentfirmaet EverSQL måtte for nylig sande, at UTF-8 ikke altid var UTF-8 - i hvert fald når det gælder MySQL, skriver EverSQL i et blogindlæg.

For de uindviede er UTF-8 det tegnsæt, som bruges til at dække over tegn fra stort set alle alfabeter og understøtter også en lang række symboler og emojis. Men det optager plads. Helt bestemt fire bytes for hvert tegn, hvis man skal have det hele med.

Det har måske været årsagen til, at MySQL i sin tid valgte at kun at understøtte en delmængde af UTF-8 ved blot at bruge tre bytes i stedet for fire.

Problemet for konsulenten fra EverSQL var, at en kunde havde problemer med, at data slet ikke blev skrevet i databasen, selvom SQL-forespørgslen så rigtig ud. Både inputtet og tabellen i databasen var UTF-8, så det burde ikke have været tegnsættet, der var problemet, men fejlmeddelelsen antydede noget andet.

Nanveforvirring

MySQL havde som sagt implementeret UTF-8 med blot tre bytes, men når man konfigurerede tabellen i databasen, valgte man det stadig under navnet 'UTF-8'.

Senere har MySQL tilføjet et tegnsæt med fire bytes som blev kaldt utf8mb4, og det gamle tegnsæt skiftede sådan set også navn til utf8mb3. Men af hensyn til bagudkompatibiliteten var navnet 'UTF-8' i konfigurationen stadig det samme som utf8mb3.

Så når man som i dette tilfælde stod med en applikation, som sendte fire byte tegn til en tabel, der forventede op til tre bytes pr. tegn, så gik det galt.

Forvirringen hos EverSQL er ikke unik, hvis man ser på forskellige vejledninger til UTF-8 i MySQL på nettet. Den gode nyhed er, at med MySQL 8, som er på vej, bliver UTF-8 med fire bytes, utf8mb4, standardformatet i MySQL-tabeller, skriver MySQL's Morgan Tucker i et blogindlæg og et svar til EverSQL.

Samtidig vil utf8mb3 også blive sat som 'forældet', men vil stadig være understøttet af hensyn til bagudkompatibiliteten. Problemet er, at man skal genopbygge en tabel, hvis man skifter tegnsæt, både hvis man skifter fra Latin1, UTF-8 eller et andet tegnsæt til utf8mb4. Derfor vil mange foretrække at holde fast i tidligere tegnsæt.

Ifølge MySQL skulle der ikke være nogen problemer med ydelsen ved at skifte til det fire bytes-baserede utf8mb4.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk

Følg forløbet

Kommentarer (5)

Kommentarer (5)
Joe Sørensen

Jeg begundte også at fælle grå hård, da jeg fandt ud af at der er noget der hedder UTF-8 formal form. Naturligvis har alle implementering er UTF-8 valgt den samme formal form, bortset fra Mac OS. Dette betyder fx at bogstavet å har forskellig binær værdi på Mac OS sammenlignet med alle andre.

I MySQL vil å være lig med å uanset platform, hvis du genner med UTF8_general_ci. Men å sendt fra mac og andre å'er er forskellige, hvis du gemmer som UTF8_binary_ci. Og filnavne er mac OS å'er altid forskellige fra andre å'er.

Derfor skal man huske ikke at bruge UTF8-binary_ci i MySQL og man skal også huske at normaliserer filnavne, hvis du lader en klient vælge navnet.

Jens Østergaard Petersen

Unicode normalization forms (http://unicode.org/reports/tr15/) er nu ikke implementeret anderledes i macOS end i andre systemer. Der er mulighed for at kode mange tegn med diakritika i fire forskellige normaliseringsformer, men macOS hælder ikke til nogen af dem - og det gør andre systemer nu heller ikke. Det er død-irriterende med forskellige realiseringer af det samme tegn, men her er macOS programmeringssproget Swift nu lidt smartere end andre sprog (i hvert fald dem jeg kender,) for alle fire former bliver her tolket ens. Man skal altid normalisere data man modtager, som du rigtigtnok skriver, og man gør nok bedst i at vælge NFC, selvom NFD giver nogle ekstra muligheder for at bruge regex.

Lasse Hillerøe Petersen

MacOS normaliserer filnavne med NFD (eller tæt på), så vidt jeg husker, efter jeg (som Joe, formoder jeg) var blevet ramt af problemet, da jeg en dag stod med en Linux webserver med to fuldstændigt ens filnavne i et directory:
$ ls
Det var Sørens.html
Det var Sørens.html

Linux er i praksis vist ret ligeglad, men den gængse konvention er tilsyneladende at bruge NFC. MacOS er muligvis mere stringent med NFD. Så flytter man en tar-fil fra det ene sted til det andet (og/eller mounter et Mac-directory i en virtuel Linux måske), kan man altså uforvarende få nogle vældigt sjove resultater. Så jo, MacOS er "anderledes". (Man kan selvfølgelig også sige at det er Linux, der er anderledes.)

Windows er jeg usikker på, men det er vist noget med UTF-16, eller UCS-2?

Sune Foldager

Windows er jeg usikker på, men det er vist noget med UTF-16, eller UCS-2?

Ja det er UCS-2, dvs. UTF-16 inden de udvidede Unicode til mere end 16 bit. Det har den ret uheldige effekt at du kan have Windows filnavne som ikke er lovlig Unicode (fx fordi de indeholder halve surrogate pairs) og som dermed ikke kan repræsenteres i fx standard UTF-8. Desuden er det, som Linux, normalization-følsomt så du kan have to filer med samme visuelle navn i et directory.

Mht. macOS så bliver det sådan med APFS, Apple's nye filsystem som allerede er rullet ud på iOS og som kommer med næste version af macOS, at det bliver normalformbevarende, dvs. det gemmer det filnavn du kommer med, men normalization-insensitive dvs. to filnavne der normaliserer til det samme betragtes som ens.

Mht. Linux er det bare en samling bytes uden anden semantik.

Log ind eller opret en konto for at skrive kommentarer

Pressemeddelelser

Affecto Denmark reaches highest Microsoft Partner level

Affecto Denmark, a leading provider of data-driven solutions, has reached the highest level in the Microsoft partner ecosystem: Managed Partner.
22. jun 2017

Innovate your business with Affecto's IoT Explorer Kit

Are you unsure if Internet of Things fits your business strategy?
31. maj 2017

Big Data Lake Summit: Fast and Trusted Insights

If you want to outpace, outsmart and outperform your competition in a digital world, you need trusted data that can be turned into actionable business insights at speed.
24. apr 2017