成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

明明表中沒這條數據,竟然還能查出來?

數據庫 其他數據庫
品牌表使用的存儲引擎ENGINE是InnoDB,為了保證表的事務性。字符集CHARSET用的utf8mb4,可以保存一些表情符號等特殊字符。校對規則COLLATE用的utf8_unicode_ci。

1.還原問題現場

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

我查了一下服務器的日志,并沒有異常。

在我們的創建商品頁面,用戶可以選擇已有品牌,也可以自己自定義新的品牌。

前端做了一個品牌的下來列表,為了方便用戶查找,支持搜索。

用戶可以輸入關鍵字搜索品牌。

如果下拉框中出現了,則可以選擇使用。

如果下拉框中沒有數據,則在輸入框中標識這個品牌是用戶自定義的品牌。

然后通過創建商品接口,將該品牌添加到數據庫當中。

現在的問題是yoyo這個品牌,用戶自定義了,但不能保存到數據庫當中。

這就非常奇怪了。

2 分析問題

為了查明這個問題,我先查詢了數據庫中的品牌表:

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

確實沒有查出yoyo這個品牌。

但意外查出YOYO這個品牌。

圖片圖片

它是yoyo英文字母的大寫。

奇怪,我們查小寫的yoyo字符串,為什么會把大寫的YOYO查出來了?

于是,我查了brand表的表結構。

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

品牌表使用的存儲引擎ENGINE是InnoDB,為了保證表的事務性。

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

校對規則COLLATE用的utf8_unicode_ci。

字符集是一組符號和編碼的集合,而校對規則是用于比較字符集中字符的規則。

例如,utf8mb4字符集支持存儲Unicode字符,而utf8mb4_0900_ai_ci校對規則定義了如何比較這些字符。

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

以utf8mb4為例,該編碼所支持的所有COLLATE如下圖所示。

圖片圖片

主要包含了三種:

  1. 以_ci結尾的。
  2. 以_bin結尾的。
  3. 以_cs結尾的。

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

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

還有一種是bin,它是將字符串中的每一個字符用二進制數據存儲,區分大小寫。

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

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

難怪下面的這條sql:

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

數據庫中明明沒有小寫的yoyo這條數據,但卻能把大寫的YOYO數據查出來。

3.如何解決問題?

知道原因了,就好辦了。

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

這樣確實可以非常快速解決問題。

但我仔細想了一下。

品牌這種基礎數據,yoyo和YOYO正常情況下應該是同一個品牌,應該只有一個id,不區分大小寫才是正確的做法。

如果brand表的COLLATE改成了utf8mb4_bin,區分大小寫,不就會出現兩個不同的id,這樣品牌表不就會產生重復的數據,后面會導致商品也可能會重復。

如果后面商品也重復了,就會帶來非常多的問題。

因此,我們要在brand表做好控制,不應該區分大小寫,保證品牌不會重復。

既然修改brand表的COLLATE這個方案不行,那么,只能修改業務邏輯了。

目前有兩種解決方案:

  • 前端搜索品牌時,不區分大小寫。
  • 前端品牌下拉控件,改成分頁的,搜索品牌的功能,改成調用后端接口實現。

方案1適合品牌數據量少的情況。

方案2適合品牌數據量多的情況。

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

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

但這樣還不能100%保證,品牌數據在brand表中不會重復。

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

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

這樣對用戶的交互更友好一些。

這是一類問題,可以衍生一下。

有些屬性值表也有類似的問題。

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

其實,在我們的實際工作中,這樣的場景很多,趕緊排查一下代碼,看看你有沒有這個問題?

責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2021-07-28 06:10:47

拖拽設計器 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對象數據

2020-08-14 08:19:25

Shell命令行數據

2023-03-05 22:11:20

刪除文件磁盤

2024-03-04 07:37:40

MySQL記錄鎖

2023-03-03 07:40:52

MySQLSQL命令

2020-03-05 09:51:20

內存分頁映射

2021-04-01 05:40:53

分庫分表數據庫MySQL

2021-12-27 09:59:57

SpringCanal 中間件

2009-09-24 09:25:10

Hibernate批量

2024-09-27 08:44:43

2020-08-26 14:45:34

SQL數據庫數次

2020-09-02 07:05:56

手機支付

2019-12-31 10:33:57

Netty高性能內存

2017-08-22 10:49:28

DNA存儲電影
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲 精品 综合 精品 自拍 | 国产精品久久久久久久久久久久午夜片 | 国产a区| 一级毛片高清 | 亚洲视频区 | 国产亚洲精品精品国产亚洲综合 | 中文字幕精品一区二区三区在线 | 91传媒在线观看 | 亚洲精品一区二区在线观看 | 久久成人午夜 | 国产福利资源 | 日韩一区二区在线视频 | 婷婷福利视频导航 | 一区二区三区在线 | 欧 | 亚洲一区二区三区四区五区中文 | 日韩中文字幕在线视频 | tube国产| 国产成人精品在线播放 | 性做久久久久久免费观看欧美 | 精品一二区 | 国产伦精品一区二区三毛 | 亚洲一区 中文字幕 | 操射视频 | 欧美一级精品片在线看 | 国产高清视频在线观看 | 欧美精品a∨在线观看不卡 国产精品久久国产精品 | 成人精品国产一区二区4080 | 91精品在线播放 | 成人不卡| 狠狠久久 | 韩国av网站在线观看 | 日韩在线精品视频 | 欧美一级www片免费观看 | 欧美日韩成人影院 | 免费的色网站 | 亚洲精品一区二区在线观看 | 欧美国产一区二区 | 日韩中文字幕免费在线观看 | 成人免费观看男女羞羞视频 | 色噜噜狠狠色综合中国 | 福利一区二区在线 |