在不升级 mysql 的情况下直接使用 mysql utf8 存储 超过三个字节的 emoji 表情

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 由于现在数据库的版本是5.5.2,但是看网上说要直接存储emoji表情,需要升级到5.5.3然后把字符集设置为utf8mb4,但是升级数据库感觉属于敏感操作。 PHP 版本 考虑了多久之后直接考虑使用正则来替换,但是emoji表情的unicode码太多了,在网上找了一份代码,还是2年前更新的,想

由于现在数据库的版本是5.5.2,但是看网上说要直接存储emoji表情,需要升级到5.5.3然后把字符集设置为utf8mb4,但是升级数据库感觉属于敏感操作。

考虑了多久之后直接考虑使用正则来替换,但是emoji表情的unicode码太多了,在网上找了一份代码,还是2年前更新的,想了想还是算了。

PHP 版本

最简单的办法就是直接找到接受到的文本中的字符串中4个字节的内容,做rawurlencode编码,再入库。输出的时候再替换回来,然后再用rawurldecode转码回unicode到手机再解析为emoji表情。

获取字符串长度mb_strlen,按字符来截取字符串mb_substrmb_strcut是按字节来截取,有区别)。

存储

$strEncode = '';
 
$length = mb_strlen($str,'utf-8');
 
for ($i=0; $i < $length; $i++) {
    $_tmpStr = mb_substr($str,$i,1,'utf-8');
    if(strlen($_tmpStr) >= 4){
        $strEncode .= '[[EMOJI:'.rawurlencode($_tmpStr).']]';
    }else{
        $strEncode .= $_tmpStr;
    }
}
 
echo $strEncode."\n";// 周梦康123~[[EMOJI:%F0%9F%98%81]][[EMOJI:%F0%9F%98%84]]

读取

//转码回去
$strDecode = preg_replace_callback("/\[\[EMOJI:(.*?)\]\]/", function($matches){
    return rawurldecode($matches[1]);
}, $strEncode);
 
echo $strDecode."\n";

20150204001219_21486

php 就这么轻松愉快的解决了。

Java 版本

考虑到想使用php里面的套路,对原字符串逐个字符获取其长度,如果超过3个字节,那么则编码下,就能存储了,依照上次的经验,我写了如下代码

String a = "\uD83D\uDE01";// 一个 emoji 表情
byte[] bytes = a.getBytes("utf-8");
System.out.println(bytes.length);// 输出 4

单个单个的来,能获取到正确的字节数,但是如何保证切割字符串的时候是正确的呢?我找遍了城市所有的街道,都没有,找到我要的方法.

import java.net.URLEncoder;
import java.net.URLDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.UnsupportedEncodingException;
 
public class test{
 
    public static void main(String[] args) throws Exception { 
        String content = args[0];
        System.out.println(content);
        
        int strLength = content.length();
        
        String filterContent = emojiFilter(content);
        System.out.println(filterContent);
 
        String emojiStr = emojiRecovery(filterContent);
        System.out.println(emojiStr);
    }
 
    private static String emojiFilter(String str){
        String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";
 
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
 
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            try {
                matcher.appendReplacement(sb, "[[EMOJI:" + URLEncoder.encode(matcher.group(1),"UTF-8") + "]]");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        matcher.appendTail(sb);
 
        return sb.toString();
    }
 
    private static String emojiRecovery(String str){
        String patternString = "\\[\\[EMOJI:(.*?)\\]\\]";
 
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
 
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            try {
                matcher.appendReplacement(sb, URLDecoder.decode(matcher.group(1),"UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        matcher.appendTail(sb);
 
        return sb.toString();
    }
}

20150610235033_89389

20150611103503_66714

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4月前
|
存储 关系型数据库 MySQL
MySQL——数据库备份上传到阿里云OSS存储
MySQL——数据库备份上传到阿里云OSS存储
198 0
|
4月前
|
存储 关系型数据库 MySQL
mysql 使用变量存储中间结果的写法
mysql 使用变量存储中间结果的写法
|
9天前
|
关系型数据库 MySQL Linux
升级到MySQL 8.4,MySQL启动报错:io_setup() failed with EAGAIN
当MySQL 8.4启动时报错“io_setup() failed with EAGAIN”时,通常是由于系统AIO资源不足所致。通过增加AIO上下文数量、调整MySQL配置、优化系统资源或升级内核版本,可以有效解决这一问题。上述解决方案详细且实用,能够帮助管理员快速定位并处理此类问题,确保数据库系统的正常运行。
47 9
|
2月前
|
存储 关系型数据库 MySQL
PACS系统 中 dicom 文件在mysql 8.0 数据库中的 存储和读取(pydicom 库使用)
PACS系统 中 dicom 文件在mysql 8.0 数据库中的 存储和读取(pydicom 库使用)
45 2
|
2月前
|
存储 SQL 关系型数据库
MySQL 存储函数及调用
MySQL 存储函数及调用
201 3
|
2月前
|
存储 关系型数据库 MySQL
MySQL 如何存储地理信息
MySQL 如何存储地理信息
192 1
|
2月前
|
监控 关系型数据库 MySQL
如何升级MySQL数据库?
【10月更文挑战第16天】如何升级MySQL数据库?
|
3月前
|
存储 关系型数据库 MySQL
深入解析MySQL数据存储机制:从表结构到物理存储
深入解析MySQL数据存储机制:从表结构到物理存储
352 1
|
2月前
|
存储 关系型数据库 MySQL
Key_Value 形式 存储_5级省市城乡划分代码 (mysql 8.0 实例)
本文介绍了如何使用MySQL8.0数据库中的Key_Value形式存储全国统计用区划代码和城乡划分代码(5级),包括导入数据、通过数学函数提取省市区信息,以及查询5级行政区划的详细数据。
39 0
|
3月前
|
监控 关系型数据库 MySQL
如何升级mysql的版本
如何升级mysql的版本
646 2