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

Come evitare caratteri spazzatura/spazzatura durante la lettura di dati da più lingue?

Il Gujarati inizia રેલવે , corretta? E il malyalam inizia നേപ , corretta? E l'inglese avrebbe dovuto includere Bureau’s .

Questo è il classico caso di

  • I byte che hai nel client sono codificati correttamente in utf8. (Bureau è codificato nel sottoinsieme Ascii/latin1 di utf8; ma non è l'apostrofo ascii.)
  • Ti sei connesso a SET NAMES latin1 (o set_charset('latin1') o ...), probabilmente per impostazione predefinita. (Dovrebbe essere utf8 .)
  • La colonna nella tabella è stata dichiarata CHARACTER SET latin1 . (O forse è stato ereditato dalla tabella/database.) (Avrebbe dovuto essere utf8 .)

La correzione per i dati è un "ALTER in 2 fasi".

ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...;
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...;

dove le lunghezze sono abbastanza grandi e gli altri "..." hanno qualsiasi altra cosa (NOT NULL , ecc.) era già sulla colonna.

Sfortunatamente, se hai molte colonne con cui lavorare, ci vorranno molti ALTER. Puoi (dovresti) MODIFY tutte le colonne necessarie a VARBINARY per una singola tabella in una coppia di ALTERs .

La correzione per il codice è stabilire utf8 come connessione; questo dipende dall'API utilizzata in PHP. Gli ALTERs cambierà la definizione della colonna.

Modifica

Hai VARCHAR con il CHARACTER SET errato . Quindi, vedi Mojibake come રેલ . La maggior parte delle tecniche di conversione cerca di preservare રેલ , ma non è quello che ti serve. Invece, fare un passaggio su VARBINARY conserva i bit ignorando la vecchia definizione dei bit che rappresentano caratteri con codifica latin1. Il secondo passaggio conserva ancora i bit, ma ora afferma che rappresentano caratteri utf8.