抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Mysql小记

外键约束

设置主从表主键、外键(主键所在为主表,外键所在为从表)的时候,注意外键约束属性

  • CASCADE : 父表delete/updatate时,子表同步delete/update关联记录
  • SET NULL : 父表delete/update, 子表将关联记录的关键字段所在列设为null, 因此设计子表时外键不能设为not null
  • RESTRICT : 如果子表中有关联父表的记录,那么想要删除父表记录时会不允许
  • NO ACTION : 同RESTRICT,子表有匹配记录就不允许父表update/delete

但是,目前其实很多场景不需要数据库中的真实外键,只用设计逻辑外键就行
真实外键存在的情况下:

  • 一是不方便数据测试
  • 二是高并发造成死锁
  • 三是一致性事务完全交给数据库处理,很多时候资源占用高

关键词查询/模糊匹配

涉及关键字查询或者模糊匹配的时候可以用 通配符模糊匹配、内置函数检索、正则匹配查询、全文索引

  • 通配符有 % _ 加上like操作符
  • 内置函数有 instr() locate() position() 等,语法接近
  • mysql 支持绝大部分正则表达式功能,基于 regexp/rlike 等,基本涵盖所有需求
  • 全文索引是mysql索引中的一种,支持字段格式包括charvarchartext,语法为match(#{字段名}) against(#{keyWord})。若不存在任何匹配结果,返回0;否则根据匹配次数多少和位置先后返回一个匹配度。

布尔值

true, false, 1 , 0

mysql中没有内置布尔类型,使用tinyint(1)来作为其等效进行存储,同时提供booleanbool作为tinyint(1)的同义词。0被认为是false非零值被认为true。而默认使用truefalse时,计算值为10


NULL值与字符串空值

一般来说,''空值说的是字符串是空的,也就是个空串;而NULL值的是一个字段未知,即unkonwn,两者不能混为一谈

特别注意,针对于NULL值是有特殊的处理运算符的:IS NULL, IS NOT NULL,所以用=!=><是不行的;
但是有一个特例:<=>运算,形如exp <=> NULL,如果exp的值是NULL,会返回1

另外,有一些针对NULL的函数:

  • IFNULL(exp): 如果exp的值为NULL,则返回1,否则返回0
  • IFNULL(exp1, exp2): 如果exp1NULL的话那么返回exp2的值,否则返回exp1的值
  • NULLIF(exp3, exp4):如果exp3 = exp4成立,那么返回NULL值,否则返回exp1

去重

一般常用的去重方法有distinctgroup by

distinct:

用于select语句开头

  • 如果去重列具有NULL值,会保留一个NULL值并删除其他
  • 多列去重的条件下,只有所有指定列的的列信息都相同才会认为此信息重复

group by`:

通常和聚合函数如count()max()等一起使用,放在where条件之后

  • 可以单列/多列去重(mysql5.7之后默认SQL模式包括ONLY_FULL_GROUP_BY,默认要求使用group by时去重列即查询列。可以打破,重新设置)
  • 去重的时候,group by会根据去重字段分组,如果数据相同那么就会分到一个组里面,再返回每个组的第一条数据,完成去重

效率的话,mysql8.0之前group by有个隐式排序:

在Mysql8.0之前,Group by会默认根据作用字段(Group by的后接字段)对结果进行排序。在能利用索引的情况下,Group by不需要额外进行排序操作;但当无法利用索引排序时,Mysql优化器就不得不选择通过使用临时表然后再排序的方式来实现GROUP BY了。且当结果集的大小超出系统设置临时表大小时,Mysql会将临时表数据copy到磁盘上面再进行操作,语句的执行效率会变得极低。这也是Mysql选择将此操作(隐式排序)弃用的原因。

所以,从8.0开始,在语义相同,不论有无索引的情况下二者效率相同;
在8.0之前,如果没有索引,group by会进行隐式排序,触发filesort,效率低

另外: 有的场景需要针对去重之后的数据作统计,可以使用count()函数,以去重字段为计数条件


连接查询

一般连接查询的语法:

1
select column from table1 #{连接方式} table2 on #{连接条件}

内连接inner join

这种方式是提取两张表的共同点,即交集;且是系统默认的连接方式,可以省略inner

左连接left join

此方式查询左表table1的的全部内容以及右表table2中符合条件的记录,如果table2中有些字段没有匹配到会默认使用NULL补充代替

右连接right join

同理,查询右表table2的全部内容和左表table1符合条件记录,NULL补充未匹配上字段

连接查询后面时常还会加另外的限制条件,wherehaving


using关键字

连接查询时可以用on作为连接条件,同样也可以用using,两者效果一致:
using(#{某个字段}) = on table1.#{同名字段} = talbe2.#{同名字段}

注意:

  • using关键字针对的是同名字段
  • 使用using之后在拼接表中会自动合并对应字段为一个
  • using支持同时使用多个字段

count()函数

条件计数的话里面经常和别的函数一起用,比方说if,针对某个字段的某个条件计数可以写成:

1
count(if(${condition}, 1, null))

这样写的原因是:coount()只要该行有值就会统计,null才不计

评论