關於utf8不支持emoji是由於emoji是用4個字節存儲的字符,而mysql的utf8只能存儲1-3個字節的字符。那就存不了唄php
須要更改的地方:
(1)Mysql服務器client,mysql,mysqld中須要顯式指定字符集爲utf8mb4
(2)在(1)的服務器上建立的db,須要爲utf8mb4字符集,COLLATE爲utf8mb4_unicode_ci 或 utf8mb4_general_ci
(3) 在(2)的db中建立table和存放emoji字段的字符集爲utf8mb4,collate爲爲utf8mb4_unicode_ci 或 utf8mb4_general_cihtml
Tips:
utf8mb4_unicode_ci 或 utf8mb4_general_ci之間的區別
Mysql 5.1中文手冊中關於utf8_unicode_ci與utf8_general_ci的說明:前端
當前,utf8_unicode_ci校對規則僅部分支持Unicode校對規則算法。一些字符仍是不能支持。而且,不能徹底支持組合的記號。這主要影響越南和俄羅斯的一些少數民族語言,如:Udmurt 、Tatar、Bashkir和Mari。
utf8_unicode_ci的最主要的特點是支持擴展,即當把一個字母看做與其它字母組合相等時。例如,在德語和一些其它語言中‘ß'等於‘ss'。
utf8_general_ci是一個遺留的 校對規則,不支持擴展。它僅可以在字符之間進行逐個比較。這意味着utf8_general_ci校對規則進行的比較速度很快,可是與使用utf8_unicode_ci的 校對規則相比,比較正確性較差)。
例如,使用utf8_general_ci和utf8_unicode_ci兩種 校對規則下面的比較相等:
Ä = A
Ö = O
Ü = U
兩種校對規則之間的區別是,對於utf8_general_ci下面的等式成立:
ß = s
可是,對於utf8_unicode_ci下面等式成立:
ß = ss
對於一種語言僅當使用utf8_unicode_ci排序作的很差時,才執行與具體語言相關的utf8字符集 校對規則。例如,對於德語和法語,utf8_unicode_ci工做的很好,所以再也不須要爲這兩種語言建立特殊的utf8校對規則。
utf8_general_ci也適用與德語和法語,除了‘ß'等於‘s',而不是‘ss'以外。
若是你的應用可以接受這些,那麼應該使用utf8_general_ci,由於它速度快。不然,使用utf8_unicode_ci,由於它比較準確。
小結:
utf8_unicode_ci和utf8_general_ci對中、英文來講沒有實質的差異。
utf8_general_ci校對速度快,但準確度稍差。
utf8_unicode_ci準確度高,但校對速度稍慢。
若是你的應用有德語、法語或者俄語,請必定使用utf8_unicode_ci。通常用utf8_general_ci就夠了java
CI和BIN的區別:python
ci是 case insensitive, 即 "大小寫不敏感", a 和 A 會在字符判斷中會被當作同樣的;
bin 是二進制, a 和 A 會別區別對待.mysql
http://www.cnblogs.com/softidea/p/5668782.htmllinux
具體操做以下:
ios
CREATE DATABASE `test` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ;
mysql> create database daily default character set utf8mb4 collate utf8mb4_unicode_ci;
原文:http://blog.csdn.net/woslx/article/details/49685111git
utf-8編碼可能2個字節、3個字節、4個字節的字符,可是MySQL的utf8編碼只支持3字節的數據,而移動端的表情數據是4個字節的字符。若是直接往採用utf-8編碼的數據庫中插入表情數據,Java程序中將報SQL異常:github
java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x92\x94’ for column ‘name’ at row 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3593)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3525)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1986)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2620)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1662)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1581)
能夠對4字節的字符進行編碼存儲,而後取出來的時候,再進行解碼。可是這樣作會使得任何使用該字符的地方都要進行編碼與解碼。
utf8mb4編碼是utf8編碼的超集,兼容utf8,而且能存儲4字節的表情字符。
採用utf8mb4編碼的好處是:存儲與獲取數據的時候,不用再考慮表情字符的編碼與解碼問題。
更改數據庫的編碼爲utf8mb4:
utf8mb4的最低mysql版本支持版本爲5.5.3+,若不是,請升級到較新版本。
MySQL在 5.5.3 以後增長了 utf8mb4 字符編碼,mb4即 most bytes 4。簡單說 utf8mb4 是 utf8 的超集並徹底兼容utf8,可以用四個字節存儲更多的字符。
但拋開數據庫,標準的 UTF-8 字符集編碼是能夠用 1~4 個字節去編碼21位字符,這幾乎包含了是世界上全部能看見的語言了。
然而在MySQL裏實現的utf8最長使用3個字節,也就是隻支持到了 Unicode 中的 基本多文本平面 (U+0000至U+FFFF),包含了控制符、拉丁文,中、日、韓等絕大多數國際字符,
但並非全部,最多見的就算如今手機端經常使用的表情字符 emoji和一些不經常使用的漢字,如 「墅」 ,這些須要四個字節才能編碼出來。
http://www.zuimoban.com/jiaocheng/mysql/11256.html
5.1.34可用,最低不能低於5.1.13
修改mysql配置文件my.cnf(windows爲my.ini)
【
how to know mysql my.cnf location
/etc/my.cnf /etc/mysql/my.cnf $MYSQL_HOME/my.cnf [datadir]/my.cnf ~/.my.cnf
You can actually ask MySQL to show you the list of all locations where it searches for my.cnf (or my.ini on Windows). It is not an SQL command though. Rather, execute: $ mysqld --help --verbose In the very first lines you will find a message with a list of all my.cnf locations it looks for. On my machine it is: Default options are read from the following files in the given order: /etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf Or, on Windows: Default options are read from the following files in the given order: C:\Windows\my.ini C:\Windows\my.cnf C:\my.ini C:\my.cnf C:\Program Files\MySQL\MySQL Server 5.5\my.ini C:\Program Files\MySQL\MySQL Server 5.5\my.cnf
https://stackoverflow.com/questions/2482234/how-to-know-mysql-my-cnf-location
】
my.cnf通常在etc/mysql/my.cnf位置。找到後請在如下三部分裏添加以下內容:
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
Variable_name | Value |
---|---|
character_set_client | utf8mb4 |
character_set_connection | utf8mb4 |
character_set_database | utf8mb4 |
character_set_filesystem | binary |
character_set_results | utf8mb4 |
character_set_server | utf8mb4 |
character_set_system | utf8 |
collation_connection | utf8mb4_unicode_ci |
collation_database | utf8mb4_unicode_ci |
collation_server | utf8mb4_unicode_ci |
collation_connection 、collation_database 、collation_server是什麼不要緊。
但必須保證
系統變量 | 描述 |
---|---|
character_set_client | (客戶端來源數據使用的字符集) |
character_set_connection | (鏈接層字符集) |
character_set_database | (當前選中數據庫的默認字符集) |
character_set_results | (查詢結果字符集) |
character_set_server | (默認的內部操做字符集) |
這幾個變量必須是utf8mb4。
能夠保存utf8-mb4的一個截圖:
mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
+--------------------------+-----------------------------+
| Variable_name | Value |
+--------------------------+-----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /data/mysql/share/charsets/ |
| collation_connection | utf8mb4_general_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+-----------------------------+
11 rows in set (0.20 sec)
數據庫鏈接參數中:
characterEncoding=utf8會被自動識別爲utf8mb4,也能夠不加這個參數,會自動檢測。
而autoReconnect=true是必須加上的。
更改數據庫編碼:ALTER DATABASE caitu99 CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci
;
更改表編碼:ALTER TABLE TABLE_NAME
CONVERT TO CHARACTER SET utf8mb4
COLLATEutf8mb4_general_ci
;
若有必要,還能夠更改列的編碼
http://www.cnblogs.com/softidea/p/6135237.html
經過上面配置更改和設置。emoji字符串已經能夠存儲到mysql中的字段了。但使用navicat查看時,倒是這個樣子:
上面 的"?"在前端展現時是正常的
爲何看到emoji這種4字節字符,是這個樣子呢?
所以:
最近遇到了一個很讓人糾結的問題:emoji表情在使用的過程當中,會莫名其妙的消失,或者變成亂碼,同時數據庫用utf8mb4來存儲,可是也出現了問題,冷備事後,導入進庫的時候,變成了不可見字符,神奇的消失了!查閱了網上的解決辦法,沒有找到相應的解決方案,因而決定本身研究unicode,而且處理,發現了幾個主要知識點:unicode被邏輯分爲了17個Plane,每一個Plane存65536個代碼點。而java的 char最多隻有2字節(16 bit),也就是說,他最多隻能存儲65536個字符,而那麼問題來了,大於0x10000的這些字符怎麼處理? 很好這個辦法,java也用了一個比較委婉的辦法來解決,那麼就是Character.codePoint()用int來存儲。直接看代碼吧,代碼中有註釋解釋:
import org.eclipse.jetty.util.StringUtil; import com.google.common.base.Strings; import com.google.common.hash.Hashing; /** * <pre> * 本類的主要功能是將帶有emoji的字符串,格式化成unicode字符串,而且提供可見unicode字符反解成emoji字符 * * * 相關識知點: * <b> * Unicode平面, * BMP的字符可使用charAt(index)來處理,計數可使用length() * 其它平面字符,須要用codePointAt(index),計數可使用codePointCount(0,str.lenght())</b> * * Unicode能夠邏輯分爲17平面(Plane),每一個平面擁有65536( = 216)個代碼點,雖然目前只有少數平面被使 * 用。 * 平面0 (0000–FFFF): 基本多文種平面(Basic Multilingual Plane, BMP). * 平面1 (10000–1FFFF): 多文種補充平面(Supplementary Multilingual Plane, SMP). * 平面2 (20000–2FFFF): 表意文字補充平面(Supplementary Ideographic Plane, SIP). * 平面3 (30000–3FFFF): 表意文字第三平面(Tertiary Ideographic Plane, TIP). * 平面4 to 13 (40000–DFFFF)還沒有使用 * 平面14 (E0000–EFFFF): 特別用途補充平面(Supplementary Special-purpose Plane, SSP) * 平面15 (F0000–FFFFF)保留做爲私人使用區(Private Use Area, PUA) * 平面16 (100000–10FFFF),保留做爲私人使用區(Private Use Area, PUA) * * 參考: * 維基百科: http://en.wikipedia.org/wiki/Emoji * GITHUB: http://punchdrunker.github.io/iOSEmoji/ * 雜項象形符號:1F300-1F5FF * 表情符號:1F600-1F64F * 交通和地圖符號:1F680-1F6FF * 雜項符號:2600-26FF * 符號字體:2700-27BF * 國旗:1F100-1F1FF * 箭頭:2B00-2BFF 2900-297F * 各類技術符號:2300-23FF * 字母符號: 2100–214F * 中文符號: 303D 3200–32FF 2049 203C * Private Use Area:E000-F8FF; * High Surrogates D800..DB7F; * High Private Use Surrogates DB80..DBFF * Low Surrogates DC00..DFFF D800-DFFF E000-F8FF * 標點符號:2000-200F 2028-202F 205F 2065-206F * 變異選擇器:IOS獨有 FE00-FE0F * </pre> */ public class EmojiCharacterUtil { // 轉義時標識 private static final char unicode_separator = '&'; private static final char unicode_prefix = 'u'; private static final char separator = ':'; private static boolean isEmojiCharacter(int codePoint) { return (codePoint >= 0x2600 && codePoint <= 0x27BF) // 雜項符號與符號字體 || codePoint == 0x303D || codePoint == 0x2049 || codePoint == 0x203C || (codePoint >= 0x2000 && codePoint <= 0x200F)// || (codePoint >= 0x2028 && codePoint <= 0x202F)// || codePoint == 0x205F // || (codePoint >= 0x2065 && codePoint <= 0x206F)// /* 標點符號佔用區域 */ || (codePoint >= 0x2100 && codePoint <= 0x214F)// 字母符號 || (codePoint >= 0x2300 && codePoint <= 0x23FF)// 各類技術符號 || (codePoint >= 0x2B00 && codePoint <= 0x2BFF)// 箭頭A || (codePoint >= 0x2900 && codePoint <= 0x297F)// 箭頭B || (codePoint >= 0x3200 && codePoint <= 0x32FF)// 中文符號 || (codePoint >= 0xD800 && codePoint <= 0xDFFF)// 高低位替代符保留區域 || (codePoint >= 0xE000 && codePoint <= 0xF8FF)// 私有保留區域 || (codePoint >= 0xFE00 && codePoint <= 0xFE0F)// 變異選擇器 || codePoint >= 0x10000; // Plane在第二平面以上的,char都不能夠存,所有都轉 } /** * 將帶有emoji字符的字符串轉換成可見字符標識 */ public static String escape(String src) { if (src == null) { return null; } int cpCount = src.codePointCount(0, src.length()); int firCodeIndex = src.offsetByCodePoints(0, 0); int lstCodeIndex = src.offsetByCodePoints(0, cpCount - 1); StringBuilder sb = new StringBuilder(src.length()); for (int index = firCodeIndex; index <= lstCodeIndex;) { int codepoint = src.codePointAt(index); if (isEmojiCharacter(codepoint)) { String hash = Integer.toHexString(codepoint); sb.append(unicode_separator).append(hash.length()).append(unicode_prefix).append(separator).append(hash); } else { sb.append((char) codepoint); } } return sb.toString(); } /** 解析可見字符標識字符串 */ public static String reverse(String src) { // 查找對應編碼的標識位 if (src == null) { return null; } StringBuilder sb = new StringBuilder(src.length()); char[] sourceChar = src.toCharArray(); int index = 0; while (index < sourceChar.length) { if (sourceChar[index] == unicode_separator) { if (index + 6 >= sourceChar.length) { sb.append(sourceChar[index]); index++; continue; } // 自已的格式,與通用unicode格式不能互轉 if (sourceChar[index + 1] >= '4' && sourceChar[index + 1] <= '6' && sourceChar[index + 2] == unicode_prefix && sourceChar[index + 3] == separator) { int length = Integer.parseInt(String.valueOf(sourceChar[index + 1])); char[] hexchars = new char[length]; // 建立一個4至六位的數組,來存儲uncode碼的HEX值 for (int j = 0; j < length; j++) { char ch = sourceChar[index + 4 + j];// 4位識別碼 if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f')) { hexchars[j] = ch; } else { // 字符範圍不對 sb.append(sourceChar[index]); index++; break; } } sb.append(Character.toChars(Integer.parseInt(new String(hexchars), 16))); index += (4 + length);// 4位前綴+4-6位字符碼 } else if (sourceChar[index + 1] == unicode_prefix) { // 通用字符的反轉 // 由於第二平面之上的,已經採用了咱們本身轉碼格式,因此這裏是固定的長度4 char[] hexchars = new char[4]; for (int j = 0; j < 4; j++) { char ch = sourceChar[index + 2 + j]; // 兩位識別碼要去掉 if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f')) { hexchars[j] = ch; // 4位識別碼 } else { // 字符範圍不對 sb.append(sourceChar[index]); index++; break; } sb.append(Character.toChars(Integer.parseInt(String.valueOf(hexchars), 16))); index += (2 + 4);// 2位前綴+4位字符碼 } } else { sb.append(sourceChar[index]); index++; continue; } } else { sb.append(sourceChar[index]); index++; continue; } } return sb.toString(); } public static String filter(String src) { if (src == null) { return null; } int cpCount = src.codePointCount(0, src.length()); int firCodeIndex = src.offsetByCodePoints(0, 0); int lstCodeIndex = src.offsetByCodePoints(0, cpCount - 1); StringBuilder sb = new StringBuilder(src.length()); for (int index = firCodeIndex; index <= lstCodeIndex;) { int codepoint = src.codePointAt(index); if (!isEmojiCharacter(codepoint)) { System.err.println("codepoint:" + Integer.toHexString(codepoint)); sb.append((char) codepoint); } index += ((Character.isSupplementaryCodePoint(codepoint)) ? 2 : 1); } return sb.toString(); } }
http://www.cnblogs.com/hahahjx/p/4522913.html
其中UTF-8編碼規則閱讀自《十分鐘搞清字符集和字符編碼》,字節與十六進制的轉換參考自《 Java中byte與16進制字符串的互相轉換》。
另一個解決策略,把emoji字符替換掉:
【Java】如何檢測、替換4個字節的utf-8編碼(此範圍編碼包含emoji表情)
http://www.cnblogs.com/nick-huang/p/5507262.html
https://github.com/vdurmont/emoji-java 【百度輸入法上面的好多圖標,並無被EmojiParser.parseToUnicode替換掉】
推薦你們看 深刻MySQL字符集設置 ,區分檢查client端、server端的編碼;最簡單暴力的方式,是在全部的環節都顯式明確的指定相同的編碼。
好比使用python的MySQLdb鏈接MySQL時默認的charset是latin1,須要本身指定charset=’utf8′,即便是在服務器端的init-connect=’SET NAMES utf8′,MySQLdb也會使用latin1覆蓋該選項;能夠參照這篇文章;
關於emoji表情的話mysql的utf8是不支持,須要修改設置爲utf8mb4,才能支持, 詳細emoji表情與utf8mb4的關係 。
MYSQL 5.5 以前, UTF8 編碼只支持1-3個字節,只支持BMP這部分的unicode編碼區, BMP是從哪到哪,到 http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters 這裏看,基本就是0000~FFFF這一區。 從MYSQL5.5開始,可支持4個字節UTF編碼utf8mb4,一個字符最多能有4字節,因此能支持更多的字符集。
utf8mb4 is a superset of utf8
utf8mb4兼容utf8,且比utf8能表示更多的字符。
修改數據庫配置文件/etc/my.cnf
character-set-server=utf8mb4
collation_server=utf8mb4_unicode_ci
重啓MySQL(按照官方文檔,這兩個選項都是能夠動態設置的,可是實際的經驗是Server必須重啓一下)
已有的表修改編碼爲utf8mb4
ALTER TABLE CONVERT TO CHARACTER SET ;tbl_namecharset_name
使用下面這個語句只是修改了表的default編碼
ALTER TABLE etape_prospection CHARSET=utf8;
jdbc的鏈接字符串不支持utf8mb4,這個 這種方式 來解決的,若是服務器端設置了character_set_server=utf8mb4,則客戶端會自動將傳過去的utf-8視做utf8mb4。
utf8mb4
for servers 5.5.2 and newer. Connector/J now auto-detects servers configured with character_set_server=utf8mb4
or treats the Java encoding utf-8
passed using characterEncoding=...
as utf8mb4
in the SET NAMES=
calls it makes when establishing the connection. (Bug #54175)
其餘的client端,好比php、python須要看下client是否支持,若是不能在鏈接字符串中指定的話,能夠在獲取鏈接以後,執行」set names utf8mb4″來解決這個問題;
由於utf8mb4是utf8的超集,理論上即便client修改字符集爲utf8mb4,也會不會對已有的utf8編碼讀取產生任何問題。
http://www.tuicool.com/articles/zAnEV3?spm=5176.100239.blogcont6791.9.f4a57Y
摘要: 問題描述: 對於IOS開發來講,iOS項目由於須要用戶文本的存儲,天然就遇到了emoji等表情符號如何被mysql DB支持的問題 若是UTF8字符集且是Java服務器的話,當存儲含有emoji表情時,會拋出相似以下異常: java.sql.SQLException: Incorrect str...
對於IOS開發來講,iOS項目由於須要用戶文本的存儲,天然就遇到了emoji等表情符號如何被mysql DB支持的問題
若是UTF8字符集且是Java服務器的話,當存儲含有emoji表情時,會拋出相似以下異常:
java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x94' for column 'name' at row 1 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3593) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3525) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1986) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2620) at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1662) at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1581)
這就是字符集不支持的異常。由於UTF-8編碼有多是兩個、三個、四個字節,其中Emoji表情是4個字節,而Mysql的utf8編碼最多3個字節,因此致使了數據插不進去。
若是你的項目要進行移動產品的用戶文本的存儲,將你的DB字符集從UTF8/GBK等傳統字符集升級到utf8mb4將是勢在必行。你能夠經過應用層面轉換emoji等特殊字符,以達到原DB的兼容,我認爲可行,可是你可能走了彎路。
utf8mb4做爲utf8的super set,徹底向下兼容,因此不用擔憂字符的兼容性問題。切換中須要顧慮的主要影響是mysql須要從新啓動(雖然mysql官方文檔說能夠動態修改配置,可是通過數次測試,仍是須要重啓纔可生效),對於業務可用率的影響是須要考慮的大問題,這裏就暫時不展開討論了。
1.utf8mb4的最低mysql版本支持版本爲5.5.3+,若不是,請升級到較新版本。
mysql版本查看命令請看:查看mysql版本的四種方法;mysql安裝步驟請看:Linux中升級Mysql到Mysql最新版本的方法
2.修改database、table和column字符集。參考如下語句:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name CHANGE column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
3.修改mysql配置文件my.cnf(windows爲my.ini)
my.cnf通常在etc/mysql/my.cnf位置。找到後請在如下三部分裏添加以下內容:
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
4.重啓 MySQL Server、檢查字符集
1.)重啓命令參考:/etc/init.d/mysql restart
2.)輸入命令:mysql,進入mysql命令行(若是提示沒權限,能夠嘗試輸入mysql -uroot -p你的密碼)
3.)在mysql命令行中輸入:SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
檢查是否以下:
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+--------------------+
rows in set (0.00 sec)
特別說明下:collation_connection/collation_database/collation_server若是是utf8mb4_general_ci,沒有關係。但必須保證character_set_client/character_set_connection/character_set_database/character_set_results/character_set_server爲utf8mb4。關於這些字符集配置是幹什麼用的,有什麼區別,請參考:深刻Mysql字符集設置
5.若是你用的是java服務器,升級或確保你的mysql connector版本高於5.1.13,不然仍然沒法使用utf8mb4
這是mysql官方release note,你們能夠查看說明,並下載最新的mysql connector for java的jar包。
這裏爲你們提供一個:mysql-connector-java-5.1.31-bin.jar
同時記得修改pom配置哦~
6.檢查你服務端的db配置文件:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE
jdbc.username=root
jdbc.password=password
特別說明其中的jdbc.url配置:若是你已經升級好了mysql-connector,其中的characterEncoding=utf8能夠被自動被識別爲utf8mb4(固然也兼容原來的utf8),而autoReconnect配置我強烈建議配上,我以前就是忽略了這個屬性,致使由於緩存緣故,沒有讀取到DB最新配置,致使一直沒法使用utf8mb4字符集。
更多以下
轉自:http://segmentfault.com/blog/ilikewhite/1190000000616820
https://yq.aliyun.com/articles/6791
若是要實現存儲 emoji 表情到 RDS MySQL 實例,須要客戶端、到 RDS MySQL 實例的鏈接、RDS 實例內部 3 個方面統一使用或者支持 utf8mb4 字符集。
注:關於 utf8mb4 字符集,請參考 MySQL 官方文檔
客戶端須要保證輸出的字符串的字符集爲 utf8mb4。
以常見的 JDBC 鏈接爲例:
對於 JDBC 鏈接,須要使用 MySQL Connector/J 5.1.13(含)以上的版本。
JDBC 的鏈接串中,建議不配置 characterEncoding 選項。
注:關於 MySQL Connector/J 5.1.13,請參考 MySQL 官方 Release Notes
Step 1. 在控制檯 參數配置 中修改 character_set_server 參數爲 utf8mb4。
對於已有的實例,須要重啓數據實例,OK,完美解決………………
Step 2. 設置庫的字符集爲 utf8mb4
Step 3. 設置表的字符集爲 utf8mb4
對於 JDBC 鏈接串設置了 characterEncoding 爲 utf8 或者作了上述配置仍舊沒法正常插入emoji數據的狀況,建議在代碼中指定鏈接的字符集爲 utf8mb4,樣例代碼以下:
String query = 「set names utf8mb4」;
stat.execute(query);
https://help.aliyun.com/knowledge_detail/41702.html
Fixes bugs found since release 5.1.12.
Functionality Added or Changed
Connector/J did not support utf8mb4
for servers 5.5.2 and newer.
Connector/J now auto-detects servers configured with character_set_server=utf8mb4
or treats the Java encoding utf-8
passed usingcharacterEncoding=...
as utf8mb4
in the SET NAMES=
calls it makes when establishing the connection. (Bug #54175)
http://dev.mysql.com/doc/relnotes/connector-j/5.1/en/news-5-1-13.html
最近,將一個部署在阿里雲上的 Rails 項目,鏈接的 MySQL 數據庫的編碼,由 utf8 調整爲 utf8mb4。
實施過程不是很是順利,目前,已經部署完成,觀察了一段時間,比較穩定。
寫了本篇總結,但願能夠幫到有須要的朋友。
根本的緣由在於,採用 utf8 編碼的 MySQL 沒法保存佔位是4個字節的 Emoji 表情。
爲了使後端的項目,全面支持客戶端輸入的 Emoji 表情,升級編碼爲 utf8mb4 是最佳解決方案。
以前一篇博文有講到,不調整 MySQL 編碼,使用 rumoji 替換 Emoji 表情爲字母編號。
博客原文連接:Ruby on Rails Use MySQL DB Support iPhone emoji
http://manageyp.github.com/ruby-on-rails/2014/12/10/ruby-on-rails-use-mysql-db-support-iphone-emoji.html
可是,這樣處理至少有兩個問題:
1. Emoji 表情會持續的更新,rumoji 庫若是沒有及時更新,輸入新的表情,則會報錯。
2. 使用 rumoji 對用戶輸入的字符,作正則匹配解析,增長了系統的開銷,下降了性能。
另外,看到不少網友建議,遷移 MySQL 至 PostgreSQL、MongoDB 等,遷移成本不小,暫時不考慮。
備註:MySQL 5.5.3 版本以後,引入了 utf8mb4 字符集。
在 mysql client 端,輸入如下命令,確認 mysql server 是否支持 utf8mb4 編碼。
mysql> SHOW CHAR SET WHERE Charset LIKE "%utf8%"; +---------+---------------+--------------------+--------+ | Charset | Description | Default collation | Maxlen | +---------+---------------+--------------------+--------+ | utf8 | UTF-8 Unicode | utf8_general_ci | 3 | | utf8mb4 | UTF-8 Unicode | utf8mb4_general_ci | 4 | +---------+---------------+--------------------+--------+
至於排序規則(collation) 選擇默認的 utf8mb4_general_ci,仍是 utf8mb4_unicode_ci。
請參考下面文章的介紹,Character Set & Collation In MySQL:
http://infopotato.com/blog/index/mysql_character_set_and_collation
做者從排序的準確性,以及性能方面,告訴咱們應該選用 utf8mb4_unicode_ci 。
名稱爲:production_new 字符集選擇:utf8mb4
# config/database.yml
encoding: utf8mb4
"string".force_encoding("UTF-8")
(4) 中止 Ruby 進程,中止隊列等服務
(5) 部署項目報錯
正式版部署以前,有在本地和 Staging 作過測試。
信心滿滿的在正式版部署,執行的過程當中,遇到下面的錯誤:
Character set 'utf8mb4' is not a compiled character set and is not specified in the '/path/mysql/charsets/Index.xml' file rake aborted! Mysql2::Error: Can't initialize character set utf8mb4 (path: /path/mysql/charsets/) /path/.rvm/gems/ruby-2.0.0-p598/gems/mysql2-0.3.16/lib/mysql2/client.rb:70:in `connect' /path/.rvm/gems/ruby-2.0.0-p598/gems/mysql2-0.3.16/lib/mysql2/client.rb:70:in `initialize'
通過一番檢查後發現,錯誤是因爲當前系統上的 MySQL 客戶端版本太低致使。
# 列出全部被安裝的 mysql 包
rpm -qa | grep mysql
mysql-devel-5.1.73-3.el6_5.x86_64
mysql-5.1.73-3.el6_5.x86_64
mysql-libs-5.1.73-3.el6_5.x86_64
# 清理現有 mysql
yum list installed | grep -i mysql
yum remove mysql mysql-* # 修改安裝源,不修改源,從新安裝的仍然是 5.1 的版本 rpm -Uvh http://repo.webtatic.com/yum/el6/latest.rpm # 安裝 5.5 版本的 mysql client yum install libmysqlclient16 --enablerepo=webtatic yum install mysql55w mysql55w-libs mysql55w-devel --enablerepo=webtatic # 若是你須要安裝 mysql server,請執行 yum install mysql55w-server --enablerepo=webtatic
https://ruby-china.org/topics/24693
CREATE TABLE `ios_emoji` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID', `unicode` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Unicode編碼', `utf8` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'UTF8編碼', `utf16` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'UTF16編碼', `sbunicode` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'SBUnicode編碼', `filename` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '文件名', `filebyte` longblob COMMENT '文件內容字節', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='ios表情編碼表';
數據存儲(MySQL varchar 數據類型對UTF8 支持問題)
MYSQL 5.5 以前, UTF8 編碼只支持1-3個字節, 從MYSQL5.5開始,可支持4個字節UTF編碼,但要特殊標記。例如咱們的帖子內容項,咱們加上了這個支持。服務端mysql統一存儲爲ios5.x也就是Unicode編碼。
對應alter語句:
ALTER TABLE topic MODIFY COLUMN content varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '內容';
http://blog.csdn.net/qdkfriend/article/details/7576524?spm=5176.100239.blogcont6791.10.f4a57Y
在大字段上建立索引時,有時會碰到下面的錯誤
ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.
因爲 MySQL Innodb 引擎表索引字段長度的限制爲 767 字節,所以對於多字節字符集的大字段(或者多字段組合索引),建立索引會出現上面的錯誤。
以 utf8mb4 字符集 字符串類型字段爲例:utf8mb4 是 4 字節字符集,則默認支持的索引字段最大長度是: 767 字節 / 4 字節每字符 = 191 字符,所以在 varchar(255) 或 char(255) 類型字段上建立索引會失敗。
注:MySQL官網關於 utf8mb4 字符集的參考文檔
Step 1. RDS 控制檯 參數設置,調整參數 innodb_large_prefix 爲 ON
將 Innodb_large_prefix 修改成 on 後,對於 Dynamic 和 Compressed 格式的InnoDB 引擎表,其最大的索引字段長度支持到 3072 字節。
Step 2. 建立表的時候指定表的 row format 格式爲 Dynamic 或者 Compressed,以下示例:
create table idx_length_test_02 ( id int auto_increment primary key, name varchar(255) ) ROW_FORMAT=DYNAMIC default charset utf8mb4;
insert into idx_length_test_02 values (null,'xxxxxxxxxx');
create index idx_name on idx_length_test_02 (name);
show warnings; show create table idx_length_test_02 \G
Step 3. 修改現有表
對已經建立的表,經過下面的語句修改下表的 row_format 格式
alter table <table_name> row_format=dynamic; alter table <table_name> row_format=compressed;
https://help.aliyun.com/knowledge_detail/41707.html
emoji是iso和Mac OS系統特有的一系列「表情符號」在微博+ios設備氾濫的今天,不少人的微博中都會嵌入相似的表情符號。
不一樣於傳統上UTF8字符的3個字節(中文地區的傳統),emoji採用了4個字節的編碼方式。
這一個不算大的改變會致使系統出現相似的報錯。
Incorrect string value: ‘xF0x9Fx8Cx9FVi…’ for column ‘nick_name’ at row 1
既然是字符不能識別的報錯,只要簡單的修改字符集就能夠,個人方法是使用了uft8mb4字符集。utf8mb4字符集能夠平滑替換原有的utf8,
不過須要注意的是隻有MySQL5.1.14版本以上纔會支持utf8mb4,並且是server 和client都要在此版本之上方可。對於較舊版本的用戶支持emoji,
個人建議是先升級版本吧。
首先修改my.ini
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
重啓MySQL使配置生效,其實能夠徹底經過set names的方式實現這個調整,我這樣作的目的是爲了避免改變代碼,平滑過渡。
修改對應字段的編碼格式
ALTER TABLE `表名` CHANGE COLUMN `字段名` `字段名` 類型(長度) CHARACTER SET utf8mb4
http://blog.sina.com.cn/s/blog_600e56a60102uzp9.html
在使用 Java 開發 RDS 管理和鏈接時,您能夠參考如下方式,建議安裝JDK1.7 版本以上,經過 maven 的安裝【點此查看】。
RDS mysql 的Java 鏈接方式您能夠考慮用mysql-connector 官方有對應下載,您能夠引入對應jar包到build path,下載參考:【點此查看】 。
對應鏈接RDS MySQL 的實例參考:
import java.sql.*; public class mysqlconnection { public static void main(String[] args) { Connection conn = null; String sql; String url = "jdbc:mysql://rdssoxxxxxxxxx.mysql.rds.aliyuncs.com:3306?zeroDateTimeBehavior=convertToNull" + "user=michael&password=password&useUnicode=true&characterEncoding=UTF8"; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url); Statement stmt = conn.createStatement(); String sqlusedb = "use test_5"; int result1 = stmt.executeUpdate(sqlusedb); sql = "create table teacher(NO char(20),name varchar(20),primary key(NO))"; int result = stmt.executeUpdate(sql); if (result != -1) { sql = "insert into teacher(NO,name) values('2016001','wangsan')"; result = stmt.executeUpdate(sql); sql = "insert into teacher(NO,name) values('2016002','zhaosi')"; result = stmt.executeUpdate(sql); sql = "select * from teacher"; ResultSet rs = stmt.executeQuery(sql); ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); String separator = " "; for (int i = 1; i <= columnCount; i++) { System.out.print(metaData.getColumnLabel(i) + separator); } while (rs.next()) { System.out.println(""); for (int i = 1; i <= columnCount; i++) { System.out.print(rs.getString(i) + separator); } } } } catch (SQLException e) { System.out.println("MySQL操做錯誤"); e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
https://help.aliyun.com/knowledge_detail/41741.html
java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x94' for colum n 'name' at row 1 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3593) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3525) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1986) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2620) at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1662) at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1581)
當報以上錯誤的時候,多是java代碼中的字段與數據庫中的字段類型或者編碼不匹配,這種狀況只要統一格式或者編碼就就能夠了。
這裏主要介紹emoji的圖像插入數據庫的錯誤以及解決方法
使用mysql數據庫的時候,若是字符集是UTF-8而且在java服務器上,當存儲emoji表情的時候,會拋出以上異常(好比微信開發獲取用戶暱稱,有的用戶的暱稱用的是emoji的圖像)
這是因爲字符集不支持的異常,由於utf-8編碼有多是兩個,三個,四個字節,其中Emoji表情是四個字節,而mysql的utf-8編碼最多三個字節,因此致使數據插不進去。
解決方式:
一.從數據庫層面進行解決(mysql支持utf8mb4的版本是5.5.3+,必須升級到較新版本)
注意:
(1.修改database,table,column字符集
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE table_name CHANGE column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
(2.修改mysql配置文件my.cnf(window爲my.ini)
[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4'
(3.用的是java服務器,升級或者確保mysql connection版本高於5.1.13不然仍然不能試用utf8mb4
(4.服務器端的db配置文件
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE jdbc.username=root jdbc.password=password
若是升級了mysql-connector,其中的characterEncoding=utf8能夠自動被識別爲utf8mb4(兼容原來的utf8),而
autoReconnection(當數據庫鏈接異常中斷時,是否自動從新鏈接?默認爲false)強烈建議配上,忽略這個屬性,可能致使緩存緣故 ,
沒有讀取到DB最新的配置,致使一直沒法試用utf8mb4字符集;
詳細可見 :
http://segmentfault.com/a/1190000000616820
二.從應用層的方面進行解決
在得到數據以後往數據庫存以前先進行編碼:
URLEncoder.encode(nickName, "utf-8");
當從數據庫中取出準備顯示的時候進行解碼,
URLDecoder.decode(nickname, "utf-8");
從應用層進行解決的時候建議不要在對象getter,setter方法中直接編碼,由於放入對象的時候setter方法將nickname進行編碼,當插入數據庫的時候至關於從對象中調用getter方法將你參考取出這就將以前setter編碼過的nickname又從新解碼了,等於未對Nickname進行任何操做。依然會出現以上問題。
http://www.cnblogs.com/dashuai01/p/4601204.html
app端遇到表情圖標提交後臺MySQL數據庫報錯的最簡單的解決方式
後臺服務器錯誤日誌常見爲:Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x97\xF0\x9F...' for column 'CONTENT' at row 1。。。。。
遇到這種狀況說明數據庫字段存貯上出了問題,爲何呢,這種輸入Incorrect string value: '\xF0\x9F\x98\x97\xF0\x9F...'的問題,多數都是字符集的,之前從latain改爲gbk,從gbk改爲utf8,比utf8更多的就只有utf8mb4了。由於普通的字符串或者表情都是佔位3個字節,因此utf8足夠用了,可是移動端的表情符號佔位是4個字節,普通的utf8就不夠用了,爲了應對無線互聯網的機遇和挑戰、避免 emoji 表情符號帶來的問題、涉及無線相關的 MySQL 數據庫建議都提早採用 utf8mb4 字符集,這必需要做爲移動互聯網行業的一個技術選型的要點。
注意: 須要 >= MySQL 5.5.3版本、從庫也必須是5.5的了、低版本不支持這個字符集、複製報錯。
若是系統設計時沒注意到此問題,後期開發中才發現,就不須要總體修改數據庫編碼,只需找到相應表的相關能夠提交表情符號的字段,修改字段的編碼爲 utf8mb4. 同時數據庫連接處修改一下編碼便可。
例如:若是使用阿里數據源,spring框架下面的配置只需增長一行設置便可。
<!-- 阿里 druid數據庫鏈接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="${url}" />
<property name="username" value="${username}" />
......
<property name="connectionInitSqls" value="set names utf8mb4;"/>
在dataSource 內增長這一行 配置便可解決問題。
隨便說一下,關於linux服務器 若是使用的是比較新的 CentOS7系統的話,mysql自己可能安裝會遇到一些問題了,
由於默認的是 Mariadb而不是mysql! Mariadb是mysql的一個分支,具體就不詳細介紹,能夠本身查本爲何更名字,
使用系統自帶的repos安裝很簡單:yum install mariadb mariadb-server
systemctl start mariadb ==> 啓動mariadb
systemctl enable mariadb ==> 開機自啓動
mysql_secure_installation ==> 設置 root密碼等相關
mysql -uroot -p123456 ==> 測試登陸!
結束!
http://sanwen8.cn/p/251jbXQ.html