因为本人也是没有大厂经验的,然后只是帮导师做过一些横向项目,遇到了一些平常使用的MySQL函数,然后在这里做一些总结。
1、find_in_set()
find_in_set函数查找某个字符串是否在另外一个字符串中,如果存在,返回字符串第一次出现的位置序号;IN是查找某个字符串是否在另外一个字符串中,如果存在返回1,否则返回0。
应用场景:
需求描述:
例如修改一个子类的祖先id时,我们可以使用find_in_set()帮助我们加快操作。首先我们要确定我们要修改的id,然后利用find_in_set函数对于每行数据的ancestors列进行查询,看当前这一行数据的祖先id中是否包含我们待修改的id,如果有,那么就将该条数据返回,反之则跳过。
数据表
应用层代码
/**
* 修改子元素关系
*
* @param deptId 被修改的部门ID
* @param newAncestors 新的父ID集合
* @param oldAncestors 旧的父ID集合
*/
public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors)
{
List<SysDept> children = deptMapper.selectChildrenDeptById(deptId);
for (SysDept child : children)
{
child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
}
if (children.size() > 0)
{
deptMapper.updateDeptChildren(children);
}
}
mapper层:
<select id="selectChildrenDeptById" parameterType="Long" resultMap="SysDeptResult">
select * from sys_dept where find_in_set(#{deptId}, ancestors)
但是,对于find_in_set函数它是不走索引的,这一点在mysql优化中一定要进行注意。
2、Concat()
将多个字符串连接成一个字符串。concat(str1, str2,…) 返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。
应用场景:
因为我们指导如果使用like进行模糊搜索的话,我们在普通的sql中就写——select * from sys_dept WHERE dept_name like “%张%”,但是如果在Mybatis中你如果想要进行这种查询你应该怎么做?
这时候concat()函数的功能就凸显出来,给大家举个例子,大家就一目了然了。
(1)mapper层:
//根据@Param查询用户
User2 queryByParam(@Param("id") Integer id,@Param("name") String name);
(2)xml层:
<select id="queryByParam" resultType="com.swagger.swaggerdemo1.Pojo.User2">
select * from user2 where id = #{id} and name like concat(#{name},'%')
</select>
(3)测试层:
@Test
@Transactional
public void queryUserByParam(){
User2 user2 = userMapper.queryByParam(1,"小明");
System.out.println(user2);
}
在这里还是提醒大家,使用like查询的时候不要把%放在前面在,因为这样会走全表搜索,不会走索引,这也是MySQL优化的一种。
Tips:
你知道concat_ws()吗?
其实相对于cancat函数一些注意点,只要concat拼接的参数中只要有一个参数时MULL,name他就会整体返回一个空值,并且默认使用逗号进行连接的,如果你想使用其他的分隔符分割数据怎么办呢?
这时候concat_ws就可以针对上述的缺点进行补充了。
关于具体用法,大家可以参考这篇博客:
https://blog.csdn.net/qq_43454016/article/details/123255614
3、Count()
count函数可以统计数据表中包含的记录行的总数,或者根据查询结果返回列中包含的数据行数。
但是你具体知道count(1)、count(*)、count(列名)的区别吗?
count(*):计算包括NULL值在内的行数。
count(1):计算包括NULL值在内的行数,其中的1是恒真表达式。
count(列名):计算指定列的行数,但不包含NULL值。
有人可能会问那么如果我们想要知道一个表中有多少条数据应该用哪种方法进行统计效率更高呢?
其实在这里因具体的情况而确定,InnoDB以同样的方式处理SELECT COUNT()和SELECT COUNT(1)操作,没有性能差异。 因此,建议使用符合SQL标准的count()。
count(column) 也是会遍历整张表,但是不同的是它会拿到 column 的值以后判断是否为空,然后再进行累加,那么如果针对主键需要解析内容,如果是二级索引需要再次根据主键获取内容,则要多一次 IO 操作,所以 count(column) 的性能肯定不如前两者,如果按照效率比较的话:
count(*)=count(1)>count(primary key)>count(非主键column)。