V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
Livid
V2EX  ›  MySQL

关于用 MySQL 存储 Emoji

  •  6
     
  •   Livid · 2014-10-09 02:38:07 +08:00 · 32769 次点击
    这是一个创建于 3729 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果你希望让你的网站或者 App 支持 Emoji,那么在初次设置 MySQL 时,有一些细节你需要知道。

    Emoji

    Emoji 字符的特殊之处是,在存储时,需要用到 4 个字节。而 MySQL 中常见的 utf8 字符集的 utf8_general_ci 这个 collate 最大只支持 3 个字节。所以为了能够存储 Emoji,你需要改用 utf8mb4 字符集。

    在创建表时,用类似这样的语句:

    CREATE TABLE `tbl` (...) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
    

    MySQL 版本

    utf8mb4 字符集的支持是 MySQL 5.5 的新功能,所以你需要确保你使用的 MySQL 版本至少是 5.5。基本上,2014 年以后的新项目都应该直接上 5.6 了。

    MySQL 备份和导入

    在启用了 utf8mb4 字符集之后,备份和导入时就不能再用默认参数了。

    用 mysqldump 备份时,需要加入:

    mysqldump --default-character-set=utf8mb4
    

    而在恢复备份或通过程序连接时,需要在每次连接打开之后发送下面这条 SQL 指令:

    SET CHARSET utf8mb4
    
    41 条回复    2019-02-22 18:51:53 +08:00
    cevincheung
        1
    cevincheung  
       2014-10-09 03:49:39 +08:00
    通过在移动设备上测试http post到服务器后直接入库,然后http get json response得到的还是问号。
    andybest
        2
    andybest  
       2014-10-09 05:37:55 +08:00   ❤️ 1
    不太明白,Emoji 字符 是什么?是指将 Emoji 表情图片以二进制整个存入数据库?
    还是指一个 utf8_general_ci 字符集不包含的字符范围内的某部分字?
    0bit
        3
    0bit  
       2014-10-09 06:58:16 +08:00
    这个经验真的很好,尤其是备份恢复那个,没有注意设置编码,所以都变成了问号。
    that
        4
    that  
       2014-10-09 08:16:58 +08:00
    受用,已收藏
    NemoAlex
        5
    NemoAlex  
       2014-10-09 08:19:53 +08:00 via iPhone   ❤️ 1
    @andybest 后者
    est
        6
    est  
       2014-10-09 09:16:31 +08:00
    其实个人觉得不用整个库都用utf8mb4,响应varchar或者text字段指定用 utf8mb4 即可。(不知道可不可以这样)
    mengzhuo
        7
    mengzhuo  
       2014-10-09 09:18:10 +08:00 via iPhone   ❤️ 1
    @andybest 比如这些字符 🐶
    GitFree
        8
    GitFree  
       2014-10-09 09:28:57 +08:00 via Android
    没必要为了几个字段把全表都搞成utf8mb4吧?建议有表情的字段还用varchar,存之前pickle.dumps一下,用之前pickle.loads一下
    ipconfiger
        9
    ipconfiger  
       2014-10-09 09:37:40 +08:00
    @est 阿里云上的RDS之前没升级到5.5,又要支持emoji,结果只好把字符串base64一下存,取出来的时候再base64一次,蛋痛死了
    RainFlying
        10
    RainFlying  
       2014-10-09 09:57:47 +08:00
    我厂很久之前就很蛋疼地把 Emoj 存进去了。。
    juicy
        11
    juicy  
       2014-10-09 10:15:26 +08:00
    那么就是说数据库会把四个字节的emoji字符截取三个字节来存储么?
    qdvictory
        12
    qdvictory  
       2014-10-09 10:25:31 +08:00
    如果是5.5以下版本,可以将相关字段转为二进制存储。
    Esay
        13
    Esay  
       2014-10-09 10:47:22 +08:00
    可以贴代码了?
    felinx
        14
    felinx  
       2014-10-09 10:47:38 +08:00
    @ipconfiger 蛋还在不在?
    too
        15
    too  
       2014-10-09 10:51:00 +08:00
    遇到过这个问题。似乎用低版本的客户端连接还不行呢,对于中央数据库这种,其他客户端连上来的版本都得升级...
    neekey
        16
    neekey  
       2014-10-09 10:53:54 +08:00
    fly2never
        17
    fly2never  
       2014-10-09 11:04:27 +08:00
    我们是数据库编码全换,几年前的事情了
    Livid
        18
    Livid  
    MOD
    OP
       2014-10-09 11:31:47 +08:00
    @Esay 是的,V2EX 会在 10 月公布新的 Markdown 发帖接口,带有 GitHub Flavored Markdown 的语法高亮功能。
    Esay
        19
    Esay  
       2014-10-09 11:34:51 +08:00
    @Livid 赞,但是估计对第三方应用开发的同学是个挑战
    6711411
        20
    6711411  
       2014-10-09 12:46:51 +08:00
    改为 utf8mb4 之后索引的名字的长度也是个问题.
    LINAICAI
        21
    LINAICAI  
       2014-10-09 14:41:54 +08:00
    顶,以后用到
    Emory_M
        22
    Emory_M  
       2014-10-09 15:59:07 +08:00
    Emoji字符在node.js截取会出现问题,产生unicode乱码,使输出JSON无法通过iOS原生的JSON解析器~
    Keinez
        23
    Keinez  
       2014-10-10 03:11:34 +08:00
    Emoji字符集的BUG我们上个月就遇到了……
    pubby
        24
    pubby  
       2014-10-14 20:18:42 +08:00
    我说怎么没碰到这个问题,原来我存的时候就是评论和一堆东西 json_encode()后存的,取出来 json_decode() 后展示的
    imlewc
        25
    imlewc  
       2015-01-30 12:29:11 +08:00
    mysql 5.5.3最低版本 纠结了好久 原来我的5.5.2.。。。
    mingyun
        26
    mingyun  
       2015-05-24 13:47:02 +08:00
    @pubby json_encode后decode能正常显示吗
    pubby
        27
    pubby  
       2015-05-24 15:58:50 +08:00
    @mingyun php中json_encode后会变成\uXXXX 因此没有问题
    lzvezr
        28
    lzvezr  
       2018-12-08 16:45:15 +08:00 via Android   ❤️ 1
    @Emory_M 应该是 js 的问题,带有 emoji 的字符串 emoji 会被拆分成两个字符,影响到长度,排序,码点转换,正则等方面,在 es6 里有解决方案
    liuyanjun0826
        29
    liuyanjun0826  
       2018-12-08 16:49:16 +08:00
    我们公司没有应用最新版本的软件,因为没有钱采购最新版本的硬件
    greatx
        30
    greatx  
       2018-12-08 16:55:42 +08:00
    2014 年的帖子
    xbigfat
        31
    xbigfat  
       2018-12-08 17:00:24 +08:00
    刚做好 mysql 的消息存储,看到帖子,试着发了一个 emoji 果然直接挂了。。。😂(试一下 v2 )
    (图片)[https://imgchr.com/i/F3OhE4]
    Sylv
        32
    Sylv  
       2018-12-08 17:06:36 +08:00 via iPhone
    @Livid
    奇怪,2014 年的帖子为什么突然跑到首页了?
    Linxing
        33
    Linxing  
       2018-12-08 17:08:38 +08:00
    我们都是前端转码存
    leoleoasd
        34
    leoleoasd  
       2018-12-08 17:08:42 +08:00
    @Sylv #32 有人回复了一下..
    Sylv
        35
    Sylv  
       2018-12-08 17:11:25 +08:00 via iPhone
    @leoleoasd 一般老帖即使有新回复也不会被顶到首页,首页只有近一两天的帖子。
    tomoya92
        36
    tomoya92  
       2018-12-08 17:15:03 +08:00 via iPhone
    @Sylv 看看帖子作者是谁🙈
    lzvezr
        37
    lzvezr  
       2018-12-08 17:18:19 +08:00 via Android
    咦,原来是 14 年的吗?完全没注意到
    xiangyuecn
        38
    xiangyuecn  
       2018-12-08 18:23:15 +08:00
    也许人家起初压根就只想支持 0x00-0xff,吧,现在还不默认支持一下 0x00-0xff ff ff ff,每次上一次痛一次,多写代码味道很不错。底层直接把支持 3 字节改到支持 4 字节,目测对 98%的吃瓜开发者是透明而且是无痛的

    顺势强推篇 emoji 字节码的文章 cnblogs .com /xiangyuecn/p/8598605.html
    cyspy
        39
    cyspy  
       2018-12-09 09:40:22 +08:00
    @andybest emoji 并不是图片
    c4f36e5766583218
        40
    c4f36e5766583218  
       2019-02-22 18:26:55 +08:00
    我使用过程中并没有调整 mysqldump,我的如下:
    1. 服务端配置调整
    [mysqld]
    character_set_server=utf8mb4
    2. 客户端
    jdbc.url=jdbc:mysql://x.x.x.x:x/x?useSSL=false&createDatabaseIfNotExist=true
    不要带上编码的那个参数
    3. 建表(/字段 /库) 添加 CHARSET=utf8mb4
    c4f36e5766583218
        41
    c4f36e5766583218  
       2019-02-22 18:51:53 +08:00
    续上,mysqldump 出来的 sql 如下:
    /*!40101 SET NAMES utf8 */;
    /*!40101 SET character_set_client = utf8 */;
    ) ENGINE=InnoDB AUTO_INCREMENT=8964 DEFAULT CHARSET=utf8mb4;
    导入成功的,支持 Emoji,我检查过了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2682 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 00:03 · PVG 08:03 · LAX 16:03 · JFK 19:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.