记录一次emoji写入到数据库发生的错误

问题描述

我在一个Web项目中,文本(content)加入了emoji的功能。

就像这样:😁👍😇

然后在调用后端接口中,报错了。

Error 3988 (HY000): Conversion from collation utf8mb3_general_ci into utf8mb4_0900_ai_ci impossible for parameter

知识点

  1. 字符集与排序规则
    • MySQL 使用字符集(charset)来定义存储的文本编码格式,最常见的是 utf8utf8mb4
    • utf8 是较旧的 UTF-8 编码格式,支持最多 3 字节的 Unicode 字符。(使用utf8默认为 utf8mb3(UTF-8 MultiByte 3-byte)!)
    • utf8mb4 是更新的 UTF-8 编码格式,支持最多 4 字节的 Unicode 字符,包括 Emoji 在内的所有 Unicode 字符。
  2. Emoji 和 UTF-8
    • Emoji 是 Unicode 字符的一部分,一些 Emoji 字符需要 4 字节才能正确存储和处理,因此需要使用 utf8mb4 字符集。

问题根因:

  • 数据库表的字符集和排序规则未正确配置为 utf8mb4,而是使用了较旧的 utf8
  • 当尝试向 utf8 字符集的表插入包含 Emoji 的文本时,MySQL 无法将 utf8mb3 转换为 utf8mb4,因为 utf8mb3 不支持 Emoji 和其他 4 字节的 Unicode 字符。

代码

在初始化数据库时代码需要改动:

	driverName := "mysql"
	user := "root"
	password := "123456"
	host := "localhost"
	port := "3306"
	database := "MyDatabase"
	charset := "utf8mb4" // charset := "utf8" 是默认 utf8mb3 !
	loc := "Asia/Shanghai"
	args := fmt.Sprintf("%s:%s@(%s:%s)/%s?charset=%s&parseTime=true&loc=%s",
		user,
		password,
		host,
		port,
		database,
		charset,
		url.QueryEscape(loc))
	db, err := gorm.Open(driverName, args)

另外在数据库定义:

  • 数据库schema

  • 确保数据库使用的字符集和排序规则是 utf8mb4

    • 通过修改表的 COLLATE 属性来实现,例如:ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
  • 修改具体字段的字符集:

    • CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci
posted @   江水为竭  阅读(147)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示