likes
comments
collection
share

SQL字符串查询的那些坑儿~

作者站长头像
站长
· 阅读数 37

哈喽,大家好,最近也是好久没更新了,都在忙于工作,这篇分享一个在工作中遇到了一个非常小但却又有点坑儿的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'

在这张表我们简单的插入三条数据,插入语句如下:

INSERT INTO t(name) VALUES("serena "); # 插入尾部带有空格的"serena "
INSERT INTO t(name) VALUES("Serena"); # 插入首字母为大写的"Serena"
INSERT INTO t(name) VALUES("serena"); #  插入"serena"

可以看到,在第一条插入语句,我们插入一个值为"serena "的字符串,注意这个字符串尾部是包含空格的。第二条插入语句中,我们插入首字母为大写的"Serena"。第三个插入语句中,我们则插入值为"serena"的记录。

接下来,我们简单的执行如下

SELECT * FROM t WHERE `name` = 'serena'

查询结果如下:

SQL字符串查询的那些坑儿~

从查询结果可以看到,该条SQL语句将刚才我们插入的三条数据都查询了出来,看似简单的SQL语句以及明了的查询结果,我们可以得到:

在建表时,我们使用了COLLATE=utf8mb4_general_ci的排序规则,排序规则(Collation)是比较和排序字符串的一种规则,每个字符集都会有默认的排序规则。

排序规则我们可以通过SHOW CHARSET来进行查看:

SQL字符串查询的那些坑儿~

排序规则_ci结尾表示不区分大小写(Case Insentive),_cs 表示大小写敏感_bin表示通过存储字符的二进制进行比较

需要注意的是,比较MySQL字符串,默认采用不区分大小的排序规则,我们可以通过一个SQL来进行验证:

SQL字符串查询的那些坑儿~

另外,在字符串查询的时候,默认SQL语句会帮我们去除掉字段的前后空格,但不会去除字符串空间的空格,这个是需要注意的点,因此上述的查询语句能够将第一条加入的数据记录查询出来。

了解到这两个点后,我们回到开头,为什么说有时候这会是一个坑儿,当我们将这些诸如大小写,包含收尾空格的数据查询到内存时,在代码通过一些字符串比较,计数时,可能会因为大小写,收尾空格等原因,导致统计不准确,或者比较不准确的情况产生,从而导致我们有时候可能需要通过日志打印等方式去逐一排查,排查到最后确实简单的一个字符串排序规则的问题所导致。

go中,我们可以通过库函数来对字符串在内存中进行操作,例如:

  • 字符串比较不区分大小写strings.EqualFold()
  • 去除字符串收尾空格strings.TrimSpace()
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
}

在学习的过程中,时刻需要把控好看似简单的基础知识,有时候也会成为你排查问题时难以想到的一个问题点。

好啦,今天的分享就到这~~~

转载自:https://juejin.cn/post/7388064351503728655
评论
请登录