MySQL-utf8字符无法在Web前端正确显示

时间:2020-01-11 20:16:06

标签: mysql utf-8

我有一个数据库,该数据库具有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 字符完全还原为如何保存在数据库中,例如符号在网页上显示为€吗?

为什么会这样?

  1. 如何解决此问题并将字符集更改为utf8mb4?

任何帮助表示赞赏。

*更新*

尝试了以下步骤:

  1. 对于数据库:

    ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

  2. 对于每个表:

    ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

  3. 对于每列:

    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'

1 个答案:

答案 0 :(得分:0)

首先,让我们讨论欧元符号的Mojibake。所有这一切都适用于utf8和utf8mb4,因为欧元的编码方式与相同。

很可能是最初存储 的数据不正确。如果您可以返回到INSERT程序,请检查以下内容:

  • 要存储的字节需要UTF-8编码。客户端编程语言是什么?数据来自哪里?
  • 在插入和选择文本时的连接需要指定utf8或utf8mb4。您有连接参数吗?
  • 需要将该列声明为CHARACTER SET utf8(或utf8mb4)。听起来这总是对的。
  • HTML应该以。
  • 开头

表格中当前什么是

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 ...

请勿在其他修补程序之上应用修补程序。我花了很长时间来努力弄清字符集问题是如何发生的以及如何“解决”单个问题。但是,如果应用了错误的修复程序,我将无所适从。