1、問(wèn)題出現(xiàn)
? ? 在APP客戶端輸入搜索文章的關(guān)鍵字時(shí),不小心輸入來(lái)了一個(gè) emoji 表情符號(hào),提示出錯(cuò)了,在后臺(tái)查詢錯(cuò)誤日志信息,提示查詢出現(xiàn)了2條相同的記錄:
Caused by: org.hibernate.NonUniqueResultException: query did not return a unique result: 2
2、業(yè)務(wù)邏輯
? ? 數(shù)據(jù)庫(kù)有個(gè) tb_search_statistic 表格用來(lái)記錄用戶的搜索記錄。每次客戶端發(fā)起搜索,后臺(tái)業(yè)務(wù)先查詢下之前是否已經(jīng)存在該「關(guān)鍵字」的搜索記錄,如果沒(méi)有就插入一條新數(shù)據(jù),如果已經(jīng)存在就對(duì)其搜索次數(shù)增加 1; 在執(zhí)行查詢操作時(shí),因?yàn)榉祷亓藘蓷l記錄所以報(bào)錯(cuò)了。
3、在Nacat for MySQL 進(jìn)行問(wèn)題重現(xiàn)
? ? 果然,出現(xiàn)了兩條記錄,是不是很奇怪,明明兩個(gè)表情符號(hào)是完全不同的。其實(shí)這條查詢語(yǔ)句里面有個(gè)字符 “=” ,這個(gè)等號(hào)和 MySQL 的字符集和字符序有關(guān)系。
? ? MySQL 里存儲(chǔ)的數(shù)據(jù),只要是字符類型的字段,都會(huì)對(duì)應(yīng)一個(gè)字符集(字符集合+編碼)和字符序(字符的排序和比較),每個(gè)字符集對(duì)應(yīng)一個(gè)或多個(gè)字符序,且對(duì)應(yīng)一個(gè)默認(rèn)的字符序,在數(shù)據(jù)表里新建字段時(shí),這個(gè)字符集和字符序就確定下來(lái)了,如果不專門指定,就繼承自表格的字符集和字符序(繼承關(guān)系:服務(wù)器 <-?數(shù)據(jù)庫(kù) <- 表 <- 字段)。
? ? 在 Navicat 客戶端看下表格的字符集和字符序:
? ? 可以發(fā)現(xiàn),表格的字符集是 utf8mb4, 字符序是默認(rèn)的?utf8mb4_general_ci。因?yàn)?keyword 字段沒(méi)有專門指定,就繼承了與表格相同的字符集和字符序。
? ? 問(wèn)題的關(guān)鍵就出在這里:utf8mb4_general_ci 無(wú)法精確區(qū)分不同的 emoji 表情符號(hào),所以導(dǎo)致查詢結(jié)果出現(xiàn)多條記錄。剛才提到一個(gè)字符序可以對(duì)應(yīng)多個(gè)字符序。下面是 utf8mb4 對(duì)應(yīng)的的兩個(gè)字符序的比較:
- utf8mb4_bin:將字符串每個(gè)字符用二進(jìn)制數(shù)據(jù)編譯存儲(chǔ),區(qū)分大小寫,而且可以存二進(jìn)制的內(nèi)容。
-
utf8mb4_general_ci:ci 即 case insensitive,不區(qū)分大小寫。沒(méi)有實(shí)現(xiàn) Unicode 排序規(guī)則,在遇到某些特殊語(yǔ)言或者字符集,排序結(jié)果可能不一致。但是,在絕大多數(shù)情況下,這些特殊字符的順序并不需要那么精確。
?
4、解決方案
? ? 方案一:將字段的字符序修改為 utf8mb4_bin.?
? ? ?修改后,再次執(zhí)行查詢語(yǔ)句,結(jié)果就正好是我們期望的這條數(shù)據(jù)了:
?
? ? 方案二:在where查詢字段添加 binary 關(guān)鍵字,BINARY 不是函數(shù),是類型轉(zhuǎn)換運(yùn)算符,它用來(lái)強(qiáng)制它后面的字符串為一個(gè)二進(jìn)制字符串。
? ? 以上出現(xiàn)了一些關(guān)于字符集和字符序的術(shù)語(yǔ),其實(shí) MySQL 的一些莫名其妙的錯(cuò)誤包括“亂碼”都和它們密切相關(guān)。?所以有必要對(duì)它們有清晰的了解,如果感興趣,可以參考筆者另外一篇文章:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-669309.html
MySQL 字符集概念、原理及配置之圖文詳解文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-669309.html
到了這里,關(guān)于MySQL 條件查詢 Emoji 表情符號(hào)卻返回多條數(shù)據(jù)【包含其它表情符號(hào)】的問(wèn)題解決 - COLLATION 字符序的選擇的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!