【问题标题】:Converting charset of BLOB field to UTF-8 in MySQL在 MySQL 中将 BLOB 字段的字符集转换为 UTF-8
【发布时间】:2016-09-16 12:14:27
【问题描述】:

我最近将 MySQL 数据库从 latin1 转换为 utf-8。除了 blob 列之外,一切都进行得很顺利。在一个示例中,该字段包含显示为“菱形问号”的错误字符。

如果我从 blob 中获取这些数据,则通过 PHP 的 utf8_encode() 运行它,它显示正常。此外,如果我将 utf8_encode() 中的数据保存到 blob 字段中,我不再需要 uf8_encode() 来显示数据。

如何在不需要 PHP 干预的情况下转换 blob 数据?

更新

我尝试将 BLOB 复制到 TEXT 字段,但错误仍然存​​在。

为了提供帮助,这里是来自 BLOB 的示例数据:

十六进制:

613A313A7B733A373A22636F6E74656E74223B733A3333333A223C70207374796C653D22746578742D616C69676E3A2063656E7465723B223E0A093C7370616E207374796C653D22636F6C6F723A20726762283235352C203235352C20323535293B223E3C7370616E207374796C653D22666F6E742D73697A653A20323470783B223E4672696C616E736F707064726167202D2042696C646561726B69763C2F7370616E3E3C2F7370616E3E3C2F703E0A3C70207374796C653D22746578742D616C69676E3A2063656E7465723B223E0A093C62723E0A093C7370616E207374796C653D22666F6E742D73697A653A20323070783B223E3C7370616E207374796C653D22636F6C6F723A20726762283231312C203231312C20323131293B223E496E666F726D61736A6F6E202D20446F6B756D656E7461736A6F6E202D20507265737365202D20466F727374F87272656C7365723C2F7370616E3E3C2F7370616E3E3C2F703E0A223B7D

预期值:

a:1:{s:7:"content";s:333:"<p style="text-align: center;">
    <span style="color: rgb(255, 255, 255);"><span style="font-size: 24px;">Frilansoppdrag - Bildearkiv</span></span></p>
<p style="text-align: center;">
    <br>
    <span style="font-size: 20px;"><span style="color: rgb(211, 211, 211);">Informasjon - Dokumentasjon - Presse - Forstørrelser</span></span></p>
";}

在本例中,我最终会显示以下文本:

Frilansoppdrag - Bildearkiv

Informasjon - Dokumentasjon - Presse - Forst�rrelser

使用一些 PHP 函数,我被告知数据是 UTF8,我正在显示的页面也是 UTF8。因此,为什么我会收到特殊字符的错误,这有点令人困惑。此外,如果我将页面编码从 UTF-8 更改为 ISO-8859-15,字符显示正常。

【问题讨论】:

  • 一个题外话的问题:将文本保存在 blob 字段中而不是文本字段中的原因是什么(请参阅stackoverflow.com/questions/7071662/mysql-text-vs-blob-vs-clob)?
  • BLOB 的全部意义在于它没有与之关联的字符集。我同意@reporter - 如果您需要,使用 BLOB 有什么意义> charset 用吗?将 blob 转换为文本并解决问题。这就是你正确的做法。
  • @Mjh 我刚刚将严格的数据类型切换到文本,现在一半的数据被截断。因此,显然还有更多可以简单地将其从 blob 切换到 text。
  • 更改表,添加text 列,运行UPDATE mytable SET new_text_column = my_blob_column;。我从来没有建议通过发出转换从一种数据类型交换到另一种数据类型,这总是伴随着截断..从一个桶倒到另一个桶,不要换掉桶:)另外,如果我知道 - 你怎么用如果不需要 BLOB 类型?这种数据类型交换是否会引发另一个问题?
  • @Mjh 不用担心,我有备份:) 我认为这是由于特殊字符造成的,但我不能确定。以前开发者的想法。

标签: mysql utf-8 character-encoding blob


【解决方案1】:

如果不了解 Blob 中的编码,就无法将 BLOB 转换为 TEXT。而如果 BLOB 中的“文本”以多种方式编码,则不可能在不丢失部分文本的情况下转换为 TEXT。

查看 blob 的 HEX()。例如,如果您有 é,而 HEX 输出为 E9,则文本可能编码为 latin1。相反,如果你得到C3A9,那么你可能有utf8(或utf8mb4)。如果不先进行此分析,您可能会破坏(通过截断或变成问号)BLOB 中的“文本”。这将丢失数据!

改变看起来像:

ALTER TABLE t MODIFY c TEXT CHARACTER SET latin1  NOT NULL;  -- if E9
ALTER TABLE t MODIFY c TEXT CHARACTER SET utf8mb4 NOT NULL;  -- if C3A9

注意:

  • 一定要有备份;如果出现问题;数据可能会丢失。
  • tc 更改为您的表名和列名。
  • 添加 NULL 或 NOT NULL 以匹配当前声明。
  • 继承声明中的任何其他内容。
  • 如果我的 E9/C3A9 示例不够清楚,让我们看一些 HEX 进行进一步讨论(并包括您认为文本应该是什么。)

【讨论】:

  • F9ø 的 latin1(或 latin5 或 dec8)十六进制。我认为您期望最后一个词是Forstørrelser?所以,我的第一个 ALTER 大概就是你所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 2011-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
相关资源
最近更新 更多