Laravel数据库从旧数据库UTF-8编码问题的迁移

时间:2019-02-06 10:31:10

标签: mysql laravel utf-8 emoji

声明:是的,我已经在Stackoverflow上进行了搜索,没有,它找不到这种情况的答案。

我正在从一个论坛中迁移数据,该论坛的MySQL数据库中已有一些遗产。问题之一是表情符号的存储。

捐赠者数据库:

-- Server: 5.5.41-MariaDB
CREATE TABLE `forumtopicresponse` (
  `id` int(10) UNSIGNED NOT NULL,
  `topicid` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `userid` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `message` text NOT NULL,
  `created` int(10) UNSIGNED NOT NULL DEFAULT '0',
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

在消息列中,我收到了这样的消息:Success!ðŸ‘ðŸ‘,它显示为“成功!”

Laravel目标数据库:

-- Server: MySQL 5.7.x
CREATE TABLE `answers` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `topic_id` int(10) unsigned NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `body` text CHARACTER SET utf8mb4,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  ...keys & indexes
) ENGINE=InnoDB AUTO_INCREMENT=1254419 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

在HTML中,文档有一个<meta charset="utf-8">,为了显示该字段,我正在使用

{!! nl2br(e($answer->body)) !!}

与此同时,它仅显示为Success!ðŸ‘ðŸ‘,而不显示表情符号。

问题

如何将有效的CLEAN和UTF-8数据迁移到我的新数据库中?我想我需要一些utf编码,但无法弄清楚。

更新!解决方案

已解决。唯一的解决方案是更改Donor数据库中的表。

ALTER TABLE forumtopicresponse CHANGE message message LONGTEXT CHARACTER SET latin1;
ALTER TABLE forumtopicresponse CHANGE message message LONGBLOB;

请勿再将LONGBLOB更改为LONGTEXT:我这样丢失了数据。

当我将LONGBLOB数据迁移到Laravel目标数据库时,所有内容都会正确迁移:所有特殊字符和表情符号都已固定,并且使用UTF-8。

1 个答案:

答案 0 :(得分:0)

表情符号为十六进制F09F918D。也就是说,它是一个4字节的字符串。

MySQL的CHARACTER SET = utf8不能处理4字节的UTF-8字符串,只能处理3字节的字符串,因此不包括许多表情符号和某些中文。

当解释为latin1时,那些十六进制数字为ðŸ‘(加上第4个但不可打印的字符)。像这样显示胡言乱语称为“ Mojibake”。

因此,您有2个问题:

  • 需要将存储空间更改为utf8mb4,以便您可以存储表情符号。
  • 需要向MySQL宣布您的客户端正在使用UTF-8,而不是latin1。

请参见Trouble with UTF-8 characters; what I see is not what I stored中的“最佳做法”

另请参阅UTF-8 all the way through

这是我的fixes列表,但是您必须首先正确确定遇到哪种情况。应用错误的修复会使情况更糟。

可能存在第三个错误-将数据从5.5移动到5.7。请提供这些详细信息。