mysql/Java服務端對emoji的支持

更改好後的字符集:

亂碼

推薦大家看 深入MySQL字符集設置 ,區分檢查client端、server端的編碼;最簡單暴力的方式,是在所有的環節都顯式明確的指定相同的編碼。

比如使用python的MySQLdb連接MySQL時默認的charset是latin1,需要自己指定charset=’utf8′,即使是在服務器端的init-connect=’SET NAMES utf8′,MySQLdb也會使用latin1覆蓋該選項;可以參照這篇文章;

emoji表情與utf8mb4

關於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 tbl_name CONVERT TO CHARACTER SET charset_name;

使用下面這個語句只是修改了表的default編碼

ALTER TABLE etape_prospection CHARSET=utf8;

客戶端

jdbc的連接字符串不支持utf8mb4,這個 這種方式 來解決的,如果服務器端設置了character_set_server=utf8mb4,則客戶端會自動將傳過去的utf-8視作utf8mb4。

  • 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 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字符集。

更多如下

MySQL亂碼問題以及utf8mb4字符集
Emoji表情符號兼容方案

轉自:http://segmentfault.com/blog/ilikewhite/1190000000616820

https://yq.aliyun.com/articles/6791

RDS MySQL使用utf8mb4字符集存儲emoji表情

1. 基本原則

2. 三個條件的說明

2.1 應用客戶端

2.2 應用到 RDS MySQL 實例的連接

2.3 RDS 實例配置

3. 通過 set names 命令設置會話字符集


1. 基本原則

如果要實現存儲 emoji 表情到 RDS MySQL 實例,需要客戶端、到 RDS MySQL 實例的連接、RDS 實例內部 3 個方面統一使用或者支持 utf8mb4 字符集。

注:關於 utf8mb4 字符集,請參考 MySQL 官方文檔

2. 三個條件的說明

2.1 應用客戶端

客戶端需要保證輸出的字符串的字符集爲 utf8mb4。

2.2 應用到 RDS MySQL 實例的連接

以常見的 JDBC 連接爲例:

  • 對於 JDBC 連接,需要使用 MySQL Connector/J 5.1.13(含)以上的版本。

  • JDBC 的連接串中,建議不配置 characterEncoding 選項。

注:關於 MySQL Connector/J 5.1.13,請參考 MySQL 官方 Release Notes

2.3 RDS 實例配置

Step 1. 在控制檯  id="iframe_0.6552373443393189" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22https://img.alicdn.com/tfscom/TB1pgd3MXXXXXXgXFXXXXXXXXXX.jpg?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.6552373443393189',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 256px; height: 256px;"> 參數配置 中修改 character_set_server 參數爲 utf8mb4。

  id="iframe_0.6986702930515007" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://img01.taobaocdn.com/tfscom/TB1pQQWHXXXXXasXFXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.6986702930515007',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 849px; height: 42px;">

Step 2. 設置庫的字符集爲 utf8mb4

id="iframe_0.4480940073176961" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://img01.taobaocdn.com/tfscom/TB1VrQ6HXXXXXXgXpXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.4480940073176961',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 664px; height: 510px;"> 

Step 3. 設置表的字符集爲 utf8mb4

  id="iframe_0.06834568248005601" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://img01.taobaocdn.com/tfscom/TB163g5HXXXXXX0XpXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.06834568248005601',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 849px; height: 146px;">

3. 通過 set names 命令設置會話字符集

對於 JDBC 連接串設置了 characterEncoding 爲 utf8 或者做了上述配置仍舊無法正常插入emoji數據的情況,建議在代碼中指定連接的字符集爲 utf8mb4,樣例代碼如下:

    1. String query = set names utf8mb4”;
      stat.execute(query);

https://help.aliyun.com/knowledge_detail/41702.html

Changes in MySQL Connector/J 5.1.13 (2010-06-24)

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。
實施過程不是非常順利,目前,已經部署完成,觀察了一段時間,比較穩定。
寫了本篇總結,希望可以幫到有需要的朋友。

環境說明

  • 服務器系統 Centos,版本爲 6.5;
  • 數據庫使用的是阿里雲 RDS MySQL,版本爲 5.5.18;
  • Rails 版本爲 4.1.2;
  • mysql2 Gem, 版本爲 0.3.16。

爲什麼要使用 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 。

實施的步驟

  • (1) 在阿里雲 RDS 控制檯,新建一個數據庫
  名稱爲:production_new
  字符集選擇:utf8mb4
  • (2) 修改 database.yml 編碼
    # config/database.yml
    encoding: utf8mb4
  • (3) Ruby 程序接收和返回 JSON 數據時,強制使用 UTF-8 編碼
    "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
  • (6) 移除現有的舊版本,重新安裝 5.5 版本的客戶端
  # 清理現有 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

RDS MySQL 建索引時 Specified key was too long; max key length is 767 bytes 錯誤的處理

 

1. 錯誤原因

2. 解決步驟


在大字段上創建索引時,有時會碰到下面的錯誤

ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.

id="iframe_0.1932779565309718" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22https://img.alicdn.com/tfscom/TB1cboSLVXXXXb7XXXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.1932779565309718',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 849px; height: 65px;">

1. 錯誤原因

由於 MySQL Innodb 引擎表索引字段長度的限制爲 767 字節,因此對於多字節字符集的大字段(或者多字段組合索引),創建索引會出現上面的錯誤。

以 utf8mb4 字符集 字符串類型字段爲例:utf8mb4 是 4 字節字符集,則默認支持的索引字段最大長度是: 767 字節 / 4 字節每字符 = 191 字符,因此在 varchar(255) 或 char(255) 類型字段上創建索引會失敗。

注:MySQL官網關於 utf8mb4 字符集的參考文檔

2. 解決步驟

Step 1. RDS 控制檯  id="iframe_0.39668140077808283" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22https://img.alicdn.com/tfscom/TB1pgd3MXXXXXXgXFXXXXXXXXXX.jpg?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.39668140077808283',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 256px; height: 256px;"> 參數設置,調整參數 innodb_large_prefix 爲 ON

將 Innodb_large_prefix 修改爲 on 後,對於 Dynamic 和 Compressed 格式的InnoDB 引擎表,其最大的索引字段長度支持到 3072 字節。

id="iframe_0.9274452393306134" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22https://img.alicdn.com/tfscom/TB1f3EMLVXXXXbmXpXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.9274452393306134',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 849px; height: 369px;">

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;

   id="iframe_0.6899838721270202" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22https://img.alicdn.com/tfscom/TB1mjgLLVXXXXcxXpXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.6899838721270202',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 726px; height: 136px;">

 insert into idx_length_test_02 values (null,'xxxxxxxxxx');

id="iframe_0.8886873102760222" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22https://img.alicdn.com/tfscom/TB1dyAuLVXXXXbSaXXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.8886873102760222',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 849px; height: 51px;">

 create index idx_name on idx_length_test_02 (name);

id="iframe_0.27601987895743224" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22https://img.alicdn.com/tfscom/TB1lQwILVXXXXXWXFXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.27601987895743224',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 849px; height: 76px;">

show warnings;
show create table idx_length_test_02 \G

id="iframe_0.7714628866663065" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22https://img.alicdn.com/tfscom/TB1vAgMLVXXXXbdXpXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.7714628866663065',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 805px; height: 253px;">

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

RDS MySQL使用utf8mb4字符集存儲emoji表情

1. 基本原則

2. 三個條件的說明

2.1 應用客戶端

2.2 應用到 RDS MySQL 實例的連接

2.3 RDS 實例配置

3. 通過 set names 命令設置會話字符集


1. 基本原則

如果要實現存儲 emoji 表情到 RDS MySQL 實例,需要客戶端、到 RDS MySQL 實例的連接、RDS 實例內部 3 個方面統一使用或者支持 utf8mb4 字符集。

注:關於 utf8mb4 字符集,請參考 MySQL 官方文檔

2. 三個條件的說明

2.1 應用客戶端

客戶端需要保證輸出的字符串的字符集爲 utf8mb4。

2.2 應用到 RDS MySQL 實例的連接

以常見的 JDBC 連接爲例:

  • 對於 JDBC 連接,需要使用 MySQL Connector/J 5.1.13(含)以上的版本。

  • JDBC 的連接串中,建議不配置 characterEncoding 選項。

注:關於 MySQL Connector/J 5.1.13,請參考 MySQL 官方 Release Notes

2.3 RDS 實例配置

Step 1. 在控制檯  id="iframe_0.16393404943064321" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22https://img.alicdn.com/tfscom/TB1pgd3MXXXXXXgXFXXXXXXXXXX.jpg?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.16393404943064321',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 256px; height: 256px;"> 參數配置 中修改 character_set_server 參數爲 utf8mb4。

  id="iframe_0.42033787886162654" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://img01.taobaocdn.com/tfscom/TB1pQQWHXXXXXasXFXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.42033787886162654',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 849px; height: 42px;">

Step 2. 設置庫的字符集爲 utf8mb4

id="iframe_0.7969751526435623" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://img01.taobaocdn.com/tfscom/TB1VrQ6HXXXXXXgXpXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.7969751526435623',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 664px; height: 510px;"> 

Step 3. 設置表的字符集爲 utf8mb4

  id="iframe_0.07811268251058861" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://img01.taobaocdn.com/tfscom/TB163g5HXXXXXX0XpXXXXXXXXXX.png?_=5774380%22%20style=%22border:none;max-width:849px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.07811268251058861',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border: medium; border-image: none; width: 849px; height: 146px;">

3. 通過 set names 命令設置會話字符集

對於 JDBC 連接串設置了 characterEncoding 爲 utf8 或者做了上述配置仍舊無法正常插入emoji數據的情況,建議在代碼中指定連接的字符集爲 utf8mb4,樣例代碼如下:

    1. String query = set names utf8mb4”;
      stat.execute(query);

https://help.aliyun.com/knowledge_detail/41702.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 for MySQL 測試程序

 

  1. 在使用 Java 開發 RDS 管理和連接時,您可以參考以下方式,建議安裝JDK1.7 版本以上,通過 maven 的安裝【點此查看】。

  2. RDS mysql 的Java 連接方式您可以考慮用mysql-connector 官方有對應下載,您可以引入對應jar包到build path,下載參考:【點此查看】 。

  3. 對應連接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

發佈了4 篇原創文章 · 獲贊 10 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章