自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

明明表中沒(méi)這條數(shù)據(jù),竟然還能查出來(lái)?

數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù)
品牌表使用的存儲(chǔ)引擎ENGINE是InnoDB,為了保證表的事務(wù)性。字符集CHARSET用的utf8mb4,可以保存一些表情符號(hào)等特殊字符。校對(duì)規(guī)則COLLATE用的utf8_unicode_ci。

1.還原問(wèn)題現(xiàn)場(chǎng)

有一天下午,有用戶反饋說(shuō),它自定義的品牌:yoyo,一直都添加不成功。

我查了一下服務(wù)器的日志,并沒(méi)有異常。

在我們的創(chuàng)建商品頁(yè)面,用戶可以選擇已有品牌,也可以自己自定義新的品牌。

前端做了一個(gè)品牌的下來(lái)列表,為了方便用戶查找,支持搜索。

用戶可以輸入關(guān)鍵字搜索品牌。

如果下拉框中出現(xiàn)了,則可以選擇使用。

如果下拉框中沒(méi)有數(shù)據(jù),則在輸入框中標(biāo)識(shí)這個(gè)品牌是用戶自定義的品牌。

然后通過(guò)創(chuàng)建商品接口,將該品牌添加到數(shù)據(jù)庫(kù)當(dāng)中。

現(xiàn)在的問(wèn)題是yoyo這個(gè)品牌,用戶自定義了,但不能保存到數(shù)據(jù)庫(kù)當(dāng)中。

這就非常奇怪了。

2 分析問(wèn)題

為了查明這個(gè)問(wèn)題,我先查詢了數(shù)據(jù)庫(kù)中的品牌表:

select * from brand where `name`='yoyo';

確實(shí)沒(méi)有查出yoyo這個(gè)品牌。

但意外查出YOYO這個(gè)品牌。

圖片圖片

它是yoyo英文字母的大寫。

奇怪,我們查小寫的yoyo字符串,為什么會(huì)把大寫的YOYO查出來(lái)了?

于是,我查了brand表的表結(jié)構(gòu)。

CREATE TABLE `brand` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(30) NOT NULL COMMENT '品牌名稱',
  `create_user_id` bigint NOT NULL COMMENT '創(chuàng)建人ID',
  `create_user_name` varchar(30) NOT NULL COMMENT '創(chuàng)建人名稱',
  `create_time` datetime(3) DEFAULT NULL COMMENT '創(chuàng)建日期',
  `update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
  `update_user_name` varchar(30)  DEFAULT NULL COMMENT '修改人名稱',
  `update_time` datetime(3) DEFAULT NULL COMMENT '修改時(shí)間',
  `is_del` tinyint(1) DEFAULT '0' COMMENT '是否刪除 1:已刪除 0:未刪除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci  COMMENT='品牌表';

品牌表使用的存儲(chǔ)引擎ENGINE是InnoDB,為了保證表的事務(wù)性。

字符集CHARSET用的utf8mb4,可以保存一些表情符號(hào)等特殊字符。

校對(duì)規(guī)則COLLATE用的utf8_unicode_ci。

字符集是一組符號(hào)和編碼的集合,而校對(duì)規(guī)則是用于比較字符集中字符的規(guī)則。

例如,utf8mb4字符集支持存儲(chǔ)Unicode字符,而utf8mb4_0900_ai_ci校對(duì)規(guī)則定義了如何比較這些字符。

在MySQL中使用show collation指令,可以查看到所有COLLATE。

以u(píng)tf8mb4為例,該編碼所支持的所有COLLATE如下圖所示。

圖片圖片

主要包含了三種:

  1. 以_ci結(jié)尾的。
  2. 以_bin結(jié)尾的。
  3. 以_cs結(jié)尾的。

ci是case insensitive的縮寫,意思是大小寫不敏感,即忽略大小寫。

cs是case sensitive的縮寫,意思是大小寫敏感,即區(qū)分大小寫。

還有一種是bin,它是將字符串中的每一個(gè)字符用二進(jìn)制數(shù)據(jù)存儲(chǔ),區(qū)分大小寫。

使用最多的是 utf8mb4_general_ci(默認(rèn)的)和 utf8mb4_bin。

我們的brand表,使用的COLLATE是utf8mb4_general_ci,它不區(qū)分大小寫。

難怪下面的這條sql:

select * from brand where `name`='yoyo';

數(shù)據(jù)庫(kù)中明明沒(méi)有小寫的yoyo這條數(shù)據(jù),但卻能把大寫的YOYO數(shù)據(jù)查出來(lái)。

3.如何解決問(wèn)題?

知道原因了,就好辦了。

第一個(gè)想到的是把brand表的COLLATE改成utf8mb4_bin不就搞定了?

這樣確實(shí)可以非常快速解決問(wèn)題。

但我仔細(xì)想了一下。

品牌這種基礎(chǔ)數(shù)據(jù),yoyo和YOYO正常情況下應(yīng)該是同一個(gè)品牌,應(yīng)該只有一個(gè)id,不區(qū)分大小寫才是正確的做法。

如果brand表的COLLATE改成了utf8mb4_bin,區(qū)分大小寫,不就會(huì)出現(xiàn)兩個(gè)不同的id,這樣品牌表不就會(huì)產(chǎn)生重復(fù)的數(shù)據(jù),后面會(huì)導(dǎo)致商品也可能會(huì)重復(fù)。

如果后面商品也重復(fù)了,就會(huì)帶來(lái)非常多的問(wèn)題。

因此,我們要在brand表做好控制,不應(yīng)該區(qū)分大小寫,保證品牌不會(huì)重復(fù)。

既然修改brand表的COLLATE這個(gè)方案不行,那么,只能修改業(yè)務(wù)邏輯了。

目前有兩種解決方案:

  • 前端搜索品牌時(shí),不區(qū)分大小寫。
  • 前端品牌下拉控件,改成分頁(yè)的,搜索品牌的功能,改成調(diào)用后端接口實(shí)現(xiàn)。

方案1適合品牌數(shù)據(jù)量少的情況。

方案2適合品牌數(shù)據(jù)量多的情況。

我們的品牌數(shù)據(jù),其實(shí)在不斷增加,因此,決定使用方案2。

后端提供一個(gè)分頁(yè)查詢品牌的接口,并且支持不區(qū)分大小寫的模糊搜索功能。

但這樣還不能100%保證,品牌數(shù)據(jù)在brand表中不會(huì)重復(fù)。

還需要給name字段增加唯一索引。

這樣改造之后,后面用戶輸入yoyo,但數(shù)據(jù)庫(kù)中有YOYO,在品牌下拉列表中會(huì)顯示YOYO,用戶可以直接選擇使用。

這樣對(duì)用戶的交互更友好一些。

這是一類問(wèn)題,可以衍生一下。

有些屬性值表也有類似的問(wèn)題。

比如用戶自定義屬性值之后,如果業(yè)務(wù)邏輯中有通過(guò)屬性id查詢屬性值集合,再拿這個(gè)屬性值集合跟自定義屬性值做判斷的時(shí)候,就需要忽略大小寫做判斷了。

其實(shí),在我們的實(shí)際工作中,這樣的場(chǎng)景很多,趕緊排查一下代碼,看看你有沒(méi)有這個(gè)問(wèn)題?

責(zé)任編輯:武曉燕 來(lái)源: 蘇三說(shuō)技術(shù)
相關(guān)推薦

2021-07-28 06:10:47

拖拽設(shè)計(jì)器 transmat

2009-09-24 09:45:23

Hibernate批量

2023-08-09 14:03:33

2013-08-26 14:18:12

SELinux

2013-08-06 10:00:52

IDC阿里云華為

2018-01-28 15:22:03

DockerKubernetes容器

2024-05-13 00:47:37

JSON對(duì)象數(shù)據(jù)

2024-03-04 07:37:40

MySQL記錄鎖

2023-03-05 22:11:20

刪除文件磁盤

2020-08-14 08:19:25

Shell命令行數(shù)據(jù)

2023-03-03 07:40:52

MySQLSQL命令

2021-04-01 05:40:53

分庫(kù)分表數(shù)據(jù)庫(kù)MySQL

2020-03-05 09:51:20

內(nèi)存分頁(yè)映射

2021-12-27 09:59:57

SpringCanal 中間件

2024-09-27 08:44:43

2009-09-24 09:25:10

Hibernate批量

2020-08-26 14:45:34

SQL數(shù)據(jù)庫(kù)數(shù)次

2020-09-02 07:05:56

手機(jī)支付

2019-12-31 10:33:57

Netty高性能內(nèi)存

2017-08-22 10:49:28

DNA存儲(chǔ)電影
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)