- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
当你看到这个标题时,第一反应可能是想:标题搞错了吧?
答:没搞错,各位看官,听我慢慢道来.
我之前写过一篇文章《明明加了唯一索引,为什么还是产生重复数据?》,发表之后,被很多博主转载过,引起了全网很多读者的共鸣.
我最近发现,这类出人意料的线上问题,加上知识点总结,加上干货分享,更容易吸引读者.
所以,这篇文章将会延续上篇文章的风格,从一个线上问题开始.
有一天下午,有用户反馈说,它自定义的品牌:yoyo,一直都添加不成功.
我查了一下服务器的日志,并没有异常.
在我们的创建商品页面,用户可以选择已有品牌,也可以自己自定义新的品牌.
前端做了一个品牌的下来列表,为了方便用户查找,支持搜索.
用户可以输入关键字搜索品牌.
如果下拉框中出现了,则可以选择使用.
如果下拉框中没有数据,则在输入框中标识这个品牌是用户自定义的品牌.
然后通过创建商品接口,将该品牌添加到数据库当中.
现在的问题是yoyo这个品牌,用户自定义了,但不能保存到数据库当中.
这就非常奇怪了.
为了查明这个问题,我先查询了数据库中的品牌表:
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如下图所示.
主要包含了三种:
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数据查出来.
知道原因了,就好办了.
第一个想到的是把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查询属性值集合,再拿这个属性值集合跟自定义属性值做判断的时候,就需要忽略大小写做判断了.
其实,在我们的实际工作中,这样的场景很多,赶紧排查一下代码,看看你有没有这个问题?
。
如果这篇文章对您有所帮助,或者有所启发的话,帮忙扫描下发二维码关注一下,您的支持是我坚持写作最大的动力。 求一键三连:点赞、转发、在看。 关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer.
最后此篇关于表中明明没有这条数据,竟然还能查出来?的文章就讲到这里了,如果你想了解更多关于表中明明没有这条数据,竟然还能查出来?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一台 MySQL 服务器和一台 PostgreSQL 服务器。 需要从多个表中复制或重新插入一组数据 MySQL 流式传输/同步到 PostgreSQL 表。 这种复制可以基于时间(Sync)或事
如果两个表的 id 彼此相等,我尝试从一个表中获取数据。这是我使用的代码: SELECT id_to , email_to , name_to , status_to
我有一个 Excel 工作表。顶行对应于列名称,而连续的行每行代表一个条目。 如何将此 Excel 工作表转换为 SQL 表? 我使用的是 SQL Server 2005。 最佳答案 这取决于您使用哪
我想合并两个 Django 模型并创建一个模型。让我们假设我有第一个表表 A,其中包含一些列和数据。 Table A -------------- col1 col2 col3 col
我有两个表:table1,table2,如下所示 table1: id name 1 tamil 2 english 3 maths 4 science table2: p
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 1 年前。 Improve th
下面两个语句有什么区别? newTable = orginalTable 或 newTable.data(originalTable) 我怀疑 .data() 方法具有性能优势,因为它在标准 AX 中
我有一个表,我没有在其中显式定义主键,它并不是真正需要的功能......但是一位同事建议我添加一个列作为唯一主键以随着数据库的增长提高性能...... 谁能解释一下这是如何提高性能的? 没有使用索引(
如何将表“产品”中的产品记录与其不同表“图像”中的图像相关联? 我正在对产品 ID 使用自动增量。 我觉得不可能进行关联,因为产品 ID 是自动递增的,因此在插入期间不可用! 如何插入新产品,获取产品
我有一个 sql 表,其中包含关键字和出现次数,如下所示(尽管出现次数并不重要): ____________ dog | 3 | ____________ rat | 7 | ____
是否可以使用目标表中的LAST_INSERT_ID更新源表? INSERT INTO `target` SELECT `a`, `b` FROM `source` 目标表有一个自动增量键id,我想将其
我正在重建一个搜索查询,因为它在“我看到的”中变得多余,我想知道什么 (albums_artists, artists) ( ) does in join? is it for boosting pe
以下是我使用 mysqldump 备份数据库的开关: /usr/bin/mysqldump -u **** --password=**** --single-transaction --databas
我试图获取 MySQL 表中的所有行并将它们放入 HTML 表中: Exam ID Status Assigned Examiner
如何查询名为 photos 的表中的所有记录,并知道当前用户使用单个查询将哪些结果照片添加为书签? 这是我的表格: -- -- Table structure for table `photos` -
我的网站都在 InnoDB 表上运行,目前为止运行良好。现在我想知道在我的网站上实时发生了什么,所以我将每个页面浏览量(页面、引荐来源网址、IP、主机名等)存储在 InnoDB 表中。每秒大约有 10
我在想我会为 mysql 准备两个表。一个用于存储登录信息,另一个用于存储送货地址。这是传统方式还是所有内容都存储在一张表中? 对于两个表...有没有办法自动将表 A 的列复制到表 B,以便我可以引用
我不是程序员,我从这个表格中阅读了很多关于如何解决我的问题的内容,但我的搜索效果不好 我有两张 table 表 1:成员 id*| name | surname -------------------
我知道如何在 ASP.NET 中显示真实表,例如 public ActionResult Index() { var s = db.StaffInfoDBSet.ToList(); r
我正在尝试运行以下查询: "insert into visits set source = 'http://google.com' and country = 'en' and ref = '1234
我是一名优秀的程序员,十分优秀!