我有一个数据库,该数据库具有latin1默认字符集-通过运行以下语句获得的信息:
SELECT default_character_set_name FROM information_schema.SCHEMATA
WHERE schema_name =“ schemaname”;
此数据库中每个表和列的默认字符集设置为utf8。
当我查看表中的数据时,可以看到数据以utf8的形式存储,例如,货币符号€
以€
的形式存储在表中。类似的撇号也存储为’
等。
在Web前端上,我具有以下元标记,因此字符可以正确呈现。
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
但是我在网页上也看到很多我在数据库中看不到的符号吗?
当我如下更改数据库连接以包括字符集utf8时:mysql:host=myhost;dbname=mydatabase;charset=utf8
,菱形符号消失,但是其他所有utf8
字符完全还原为如何保存在数据库中,例如€
符号在网页上显示为€
吗?
为什么会这样?
任何帮助表示赞赏。
*更新*
尝试了以下步骤:
对于数据库:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
对于每个表:
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
对于每列:
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
不确定步骤3是否必要,因为当我在步骤2之后执行SHOW CREATE TABLE
时,虽然定义未显示列字符集,但确实将表的默认字符集显示为utf8mb4。为了进行健全性检查,我确实在表的其中一列上执行了第3步,但这没什么区别-€
在页面上以€
的形式呈现,并且具有数据库连接,如下所示:
`mysql:host=myhost;dbname=mydatabase;charset=utf8mb4`
我必须在要转换的每一列上运行以下内容,这似乎可以解决一些问题
UPDATE tbl_profiles SET profile =
convert(cast(convert(profile using latin1) as binary) using UTF8MB4);
但在网页上仍然看到Iâm
和«Â
和â¢
之类的字符
有什么想法吗?
*更新2 *
运行上面的步骤1和2之后,我有一个表格列,如下:
`job_salary` VARCHAR(150) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
此列上的以下查询返回以下结果:
SELECT job_salary FROM tbl_jobs WHERE job_id = 2235;
€30,000 plus excellent benefits
我在此列上执行以下语句:
UPDATE tbl_jobs SET job_salary = CONVERT(BINARY(CONVERT(job_salary USING latin1)) USING utf8mb4);
但是我收到以下错误,这意味着其他记录的utf8mb4无效
Invalid utf8mb4 character string: '\x8010000 to \x8020000 Per: annum'
答案 0 :(得分:0)
首先,让我们讨论欧元符号的Mojibake。所有这一切都适用于utf8和utf8mb4,因为欧元的编码方式与和相同。
很可能是最初存储 的数据不正确。如果您可以返回到INSERT
程序,请检查以下内容:
表格中当前什么是?
SELECT col, HEX(col) FROM ... WHERE ...
正确存储的欧元符号(€
)应该为十六进制E282AC
。 (将其解释为latin1会产生€
。
相反,如果看到的是十六进制C3A2E2809AC2AC
,则表示您具有“双重编码”,并且显示的内容可能是€
。
我已经确定了几个可能的修复程序,但尚未确定哪种方法适用于您的情况。可能的候选人是
CHARACTER SET utf8mb4
,具有双重编码:要进行验证(在修复之前),请执行以下操作:
SELECT col,
CONVERT(BINARY(CONVERT(col USING latin1)) USING utf8mb4),
HEX(
CONVERT(BINARY(CONVERT(col USING latin1)) USING utf8mb4)
)
FROM ...
WHERE ...
请勿在其他修补程序之上应用修补程序。我花了很长时间来努力弄清字符集问题是如何发生的以及如何“解决”单个问题。但是,如果应用了错误的修复程序,我将无所适从。