Man bör inte lagra Base64-kodad data i sin databas...
Base64 är en kodning där godtycklig binär data representeras med endast utskrivbara texttecken:den designades för situationer där sådana binära data behöver överföras över ett protokoll eller medium som endast kan hantera utskrivbar text (t.ex. SMTP/e-post). Det ökar datastorleken (med 33 %) och lägger till beräkningskostnaden för kodning/avkodning, så det bör undvikas om det inte är absolut nödvändigt.
Däremot hela poängen med BLOB
kolumner är att de lagrar ogenomskinliga binära strängar . Så fortsätt bara och lagra dina saker direkt i din BLOB
kolumner utan att först Base64-koda dem. (Som sagt, om MySQL har en mer lämplig typ för den specifika data som lagras, kanske du vill använda den istället:till exempel kan textfiler som JavaScript-källor dra nytta av att lagras i TEXT
kolumner för vilka MySQL spårar textspecifik metadata – mer om detta nedan).
Den (felaktiga) idén att SQL-databaser kräver utskrivbar textkodning som Base64 för att hantera godtyckliga binära data har vidmakthållits av ett stort antal dåligt informerade handledningar. Den här idén tycks ligga i den felaktiga uppfattningen att, eftersom SQL endast innehåller utskrivbar text i andra sammanhang, måste den säkert kräva det för binära data också (åtminstone för dataöverföring, om inte för datalagring). Detta är helt enkelt inte sant:SQL kan förmedla binära data på ett antal sätt, inklusive vanliga strängliteraler (förutsatt att de är korrekt citerade och escaped som vilken annan sträng som helst); självklart är det föredragna sättet att skicka data (av vilken typ som helst) till din databas genom parametriserade frågor, och datatyperna för dina parametrar kan lika gärna vara råa binära strängar som allt annat.
...såvida den inte är cachad av prestandaskäl...
Den enda situation där det kan vara någon fördel med att lagra Base64-kodad data är när den vanligtvis överförs över ett protokoll som kräver sådan kodning (t.ex. via e-postbilaga) omedelbart efter hämtas från databasen – i så fall skulle lagring av den Base64-kodade representationen spara från att behöva utföra kodningsoperationen på annars rådata vid varje hämtning.
Notera dock i denna mening att den Base64-kodade lagringen bara fungerar som en cache , ungefär som man kan lagra denormaliserad data av prestandaskäl.
...i så fall ska det vara TEXT
inte BLOB
Som nämnts ovan:den enda skillnaden mellan TEXT
och BLOB
kolumner är det för TEXT
kolumner spårar MySQL dessutom textspecifik metadata (som teckenkodning och sortering ) till dig. Denna extra metadata gör det möjligt för MySQL att konvertera värden mellan lagrings- och anslutningsteckenuppsättningar (där det är lämpligt) och utföra snygga strängjämförelser/sorteringsoperationer.
Generellt sett:om två klienter som arbetar i olika teckenuppsättningar ska se samma byte , då vill du ha en BLOB
kolumn; om de skulle se samma tecken då vill du ha en TEXT
kolumn.
Med Base64 måste dessa två klienter till slut upptäcka att data avkodas till samma byte; men de bör se att den lagrade/kodade datan har samma tecken . Anta till exempel att man vill infoga Base64-kodningen för 'Hello world!'
(som är 'SGVsbG8gd29ybGQh'
). Om infogningsprogrammet fungerar i teckenuppsättningen UTF-8, kommer det att skicka bytesekvensen 0x53475673624738676432397962475168
till databasen.
-
om den bytesekvensen är lagrad i en
BLOB
kolumn och senare hämtas av ett program som fungerar i UTF-16, samma byte kommer att returneras – som representerar'升噳扇㡧搲㥹扇全'
och inte det önskade Base64-kodade värdet; medan -
om den bytesekvensen är lagrad i en
TEXT
kolumnen och senare hämtas av ett program som fungerar i UTF-16, kommer MySQL att omkoda direkt för att returnera bytesekvensen0x0053004700560073006200470038006700640032003900790062007code1040790006850407 —som representerar det ursprungliga Base64-kodade värdet
'SGVsbG8gd29ybGQh'
som önskat.
Naturligtvis kan du ändå använda BLOB
kolumner och spåra teckenkodningen på något annat sätt – men det skulle bara i onödan uppfinna hjulet på nytt, med ökad underhållskomplexitet och risk för oavsiktliga fel.