我们创建如下一张表:
sql
代码解读
复制代码
CREATE TABLE `t` (
`id` bigint(10) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL COMMENT 'name',
PRIMARY KEY (`id`)
) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='t'
在这张表我们简单的插入三条数据,插入语句如下:
sql
代码解读
复制代码
INSERT INTO t(name) VALUES("serena "); # 插入尾部带有空格的"serena "
INSERT INTO t(name) VALUES("Serena"); # 插入首字母为大写的"Serena"
INSERT INTO t(name) VALUES("serena"); # 插入"serena"
可以看到,在第一条插入语句,我们插入一个值为"serena "
的字符串,注意这个字符串尾部是包含空格的。第二条插入语句中,我们插入首字母为大写的"Serena"
。第三个插入语句中,我们则插入值为"serena"
的记录。
接下来,我们简单的执行如下
sql
代码解读
复制代码
SELECT * FROM t WHERE `name` = 'serena'
查询结果如下:
从查询结果可以看到,该条SQL语句将刚才我们插入的三条数据都查询了出来,看似简单的SQL语句以及明了的查询结果,我们可以得到:
在建表时,我们使用了COLLATE=utf8mb4_general_ci
的排序规则,排序规则(Collation)是比较和排序字符串的一种规则,每个字符集都会有默认的排序规则。
排序规则我们可以通过SHOW CHARSET
来进行查看:
排序规则以_ci
结尾表示不区分大小写(Case Insentive),_cs
表示大小写敏感,_bin
表示通过存储字符的二进制进行比较。
需要注意的是,比较MySQL字符串,默认采用不区分大小的排序规则,我们可以通过一个SQL来进行验证:
另外,在字符串查询的时候,默认SQL语句会帮我们去除掉字段的前后空格,但不会去除字符串空间的空格,这个是需要注意的点,因此上述的查询语句能够将第一条加入的数据记录查询出来。
了解到这两个点后,我们回到开头,为什么说有时候这会是一个坑儿,当我们将这些诸如大小写,包含收尾空格的数据查询到内存时,在代码通过一些字符串比较,计数时,可能会因为大小写,收尾空格等原因,导致统计不准确,或者比较不准确的情况产生,从而导致我们有时候可能需要通过日志打印等方式去逐一排查,排查到最后确实简单的一个字符串排序规则的问题所导致。
在go
中,我们可以通过库函数来对字符串在内存中进行操作,例如:
- 字符串比较不区分大小写
strings.EqualFold()
- 去除字符串收尾空格
strings.TrimSpace()
go
代码解读
复制代码
package main
import (
"fmt"
"strings"
)
func main() {
str1 := "serena"
str2 := "Serena"
str3 := " serena "
// 字符串不区分大小写比较
fmt.Println(strings.EqualFold(str1, str2)) // true
// 字符串去除收尾空格
fmt.Println(strings.TrimSpace(str3)) // serena
}
在学习的过程中,时刻需要把控好看似简单的基础知识,有时候也会成为你排查问题时难以想到的一个问题点。