教你如何在?MySQL?數(shù)據(jù)庫中支持完整的Unicode
在你的數(shù)據(jù)庫中使用 MySQL 的 utf8 字符集嗎? 在這篇文章中,我將解釋為什么你應(yīng)該改用 utf8mb4,以及如何去做。
UTF-8
UTF-8編碼可以表示Unicode字符集中的每一個(gè)符號(hào),范圍從到。 那是 1,114,112 個(gè)可能的符號(hào)。 (并非所有這些 Unicode 代碼點(diǎn)都已分配字符,但這并不妨礙 UTF-8 能夠?qū)λ鼈冞M(jìn)行編碼。)
UTF-8 是一種可變寬度編碼;可以參考Unicode 字符集和 UTF-8、UTF-16、UTF-32 編碼這篇文章 它使用一到四個(gè) 8 位字節(jié)對(duì)每個(gè)符號(hào)進(jìn)行編碼。 具有較低數(shù)字代碼點(diǎn)值的符號(hào)使用較少的字節(jié)進(jìn)行編碼。 這樣,UTF-8 針對(duì)使用 ASCII 字符和其他 BMP 符號(hào)(其代碼點(diǎn)范圍從 到 )的常見情況進(jìn)行了優(yōu)化——同時(shí)仍然允許星體符號(hào)(其代碼點(diǎn)范圍從 到 ) 被存儲(chǔ)。
MySQL 中的 utf8
很長一段時(shí)間,我一直在為數(shù)據(jù)庫、表和列使用 MySQL 的 utf8 字符集,假設(shè)它映射到上述 UTF-8 編碼。 通過使用 utf8,我可以在我的數(shù)據(jù)庫中存儲(chǔ)我想要的任何符號(hào)——或者我是這么認(rèn)為的。
在寫 JavaScript 的內(nèi)部字符編碼時(shí),我注意到無法將 符號(hào)插入到該站點(diǎn)后面的 MySQL 數(shù)據(jù)庫中。 我嘗試更新的列具有 排序規(guī)則,并且連接字符集設(shè)置為 utf8。
mysql> SET NAMES utf8; # just to emphasize that the connection charset is set to `utf8` Query OK, 0 rows affected (0.00 sec) mysql> UPDATE database_name.table_name SET column_name = 'foo??bar' WHERE id = 9001; Query OK, 1 row affected, 1 warning (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 1 mysql> SELECT column_name FROM database_name.table_name WHERE id = 9001; +-------------+ | column_name | +-------------+ | foo | +-------------+ 1 row in set (0.00 sec)
內(nèi)容在第一個(gè) 符號(hào)處被截?cái)啵诒纠袨?— 因此,嘗試插入 實(shí)際上插入的是 ,導(dǎo)致數(shù)據(jù)丟失(并可能引入安全問題;見下文)。 MySQL 也返回一條警告消息:
mysql> SHOW WARNINGS; +---------+------+------------------------------------------------------------------------------+ | Level | Code | Message | +---------+------+------------------------------------------------------------------------------+ | Warning | 1366 | Incorrect string value: '\xF0\x9D\x8C\x86' for column 'column_name' at row 1 | +---------+------+------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
事實(shí)證明,MySQL 的 utf8 字符集僅部分實(shí)現(xiàn)了正確的 UTF-8 編碼。 它只能存儲(chǔ)由一到三個(gè)字節(jié)組成的 UTF-8 編碼符號(hào); 不支持占用四個(gè)字節(jié)的編碼符號(hào)。
由于星體符號(hào)(其代碼點(diǎn)范圍從 到 )在 UTF-8 中均由四個(gè)字節(jié)組成,因此我們不能使用 MySQL 的 utf8 實(shí)現(xiàn)來存儲(chǔ)它們。
這不僅會(huì)影響 字符,還會(huì)影響更重要的符號(hào),例如 。 總共有 1,048,575 個(gè)可能的代碼點(diǎn)是我們不能使用的。 事實(shí)上,MySQL 的 utf8 只允許我們存儲(chǔ)所有可能的 Unicode 代碼點(diǎn)的 5.88% 。 正確的 UTF-8 可以編碼所有 Unicode 代碼點(diǎn)的 100% 。
MySQL 中的 utf8mb4
幸運(yùn)的是,MySQL 5.5.3(2010 年初發(fā)布)引入了一種名為 utf8mb4 的新編碼,它映射到正確的 UTF-8,因此完全支持 Unicode,包括星體符號(hào)。
我們可以參考 MySQL 編碼utf8 與 utf8mb4 utf8mb4_unicode_ci 與 utf8mb4_general_ci
總結(jié)
永遠(yuǎn)不要在 MySQL 中使用 utf8——總是使用 utf8mb4。 更新數(shù)據(jù)庫和代碼可能需要一些時(shí)間,但絕對(duì)值得付出努力。 為什么要任意限制可以在數(shù)據(jù)庫中使用的符號(hào)集? 為什么每次用戶輸入星體符號(hào)作為評(píng)論或消息的一部分或我們存儲(chǔ)在數(shù)據(jù)庫中的任何內(nèi)容時(shí),都會(huì)丟失數(shù)據(jù)? 沒有理由不在所有地方爭取完全的 支持。 做正確的事,使用 utf8mb4。
到此這篇關(guān)于如何在 MySQL 數(shù)據(jù)庫中支持完整的 Unicode的文章就介紹到這了,更多相關(guān)mysql支持 Unicode內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
zabbix監(jiān)控MySQL主從狀態(tài)的方法詳解
這篇文章主要介紹了zabbix--監(jiān)控MySQL主從狀態(tài)的方法,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-06-06
MySQL使用IF函數(shù)動(dòng)態(tài)執(zhí)行where條件的方法
這篇文章主要介紹了MySQL使用IF函數(shù)來動(dòng)態(tài)執(zhí)行where條件,詳細(xì)介紹了IF函數(shù)在WHERE條件中的使用,MySQL的IF()函數(shù),接受三個(gè)表達(dá)式,如果第一個(gè)表達(dá)式為true,而不是零且不為NULL,它將返回第二個(gè)表達(dá)式,需要的朋友可以參考下2022-09-09
SQL實(shí)現(xiàn)LeetCode(183.從未下單訂購的顧客)
這篇文章主要介紹了SQL實(shí)現(xiàn)LeetCode(182.從未下單訂購的顧客),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
Mysql inner join on的用法實(shí)例(必看)
下面小編就為大家?guī)硪黄狹ysql inner join on的用法實(shí)例(必看)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03
詳解數(shù)據(jù)庫_MySQL: mysql函數(shù)
這篇文章主要介紹了數(shù)據(jù)庫_MySQL: mysql函數(shù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03

