用MySQL碰到的一些“坑”

Posted gdouzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用MySQL碰到的一些“坑”相关的知识,希望对你有一定的参考价值。

  本篇文章持续更新。

  这里说坑,也不算坑,只是对我一个经常用SQL Server的来说有点不习惯而已。

  一、GroupBy 的不同

create table Customer (
    CustomerNumber varchar(50),
    PayMentDate datetime,
    Amount int
)
insert into Customer(
CustomerNumber,
PayMentDate,
Amount
)
select 103,2018-01-02,123.01 union all
select 103,2018-01-08,123.01 union all
select 115,2018-01-04,123.01 union all
select 112,2018-01-05,123.01 union all
select 115,2018-01-08,123.01 union all
select 112,2018-01-10,123.01 union all
select 114,2018-01-06,123.01 ;

  根据上面的数据,我们执行如下SQL语句:

      select CustomerNumber,PayMentDate from  Customer group by CustomerNumber

      第一反应,看到这条SQL,我说这不是会报错吗(按照以前在SQLServer的逻辑)。

      实际上是不会报错的。

      虽然大家不推荐这么干,但是上面的写法确实是不会报错的,因为mysql会给我们(非分组字段)加默认的聚合函数。

      真正的原因:MySQL里面是通过sql_Model来提供SQL语句的合法检查,在mysql的sql_model=default的情况下

      是允许刚刚上面这种做法的,也就是说一条select语句,除了聚合函数和group by column以外的表达式(这个表达式的值无法确定)

    实际上是MySQL的分组内第一行对应列的值)

  而很多对语义限制比较严的多家数据库,如SQLServer,Oracle,PostgreSql都不支持select trage list 中出现语义不明确的列。

    所以MySQL在后续的版本中出现了一个修正的语义,也就是我们说的ONLY_FULL_GROUP_BY的语义。

set sql_mode=ONLY_FULL_GROUP_BY;
select CustomerNumber,PayMentDate from  Customer group by CustomerNumber;

    上面这样写就会报错:说PayMentDate不在Group By 的列中。

  不管我们是否设置:

       set sql_mode=ONLY_FULL_GROUP_BY

  我们都应该按照严格的语义来写,不然给后面维护带来不方便。

  二、删除数据

  一开始的删除数据,直接写了下面个子查询,然后就交给DBA,去正式的库执行,之后反馈说,报错了,不能执行。

delete from Customer
where CustomerNumber in (
  select CustomerNumber from payments
);

  上面这个做法为什么错呢,因为MySQL不允许在安全模式下,删除数据不通过主键来删除。

  正确的做法:

  把安全更新设置为零,用完再设置回1。

SET SQL_SAFE_UPDATES = 0;
delete from Customer
where CustomerNumber in (
  select CustomerNumber from payments
);
SET SQL_SAFE_UPDATES=1;

  从这里也可以看出,我们进行删除数据这些操作,还是尽量的用主键好。主键能够保证不会多删,并且效率也高。

以上是关于用MySQL碰到的一些“坑”的主要内容,如果未能解决你的问题,请参考以下文章

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑——对 run.py 的调整

能避开很多坑的mysql面试题,你知道吗?

ffmpeg-3.14居然也有这么坑的bug

手写一个博客平台 ~ 第七天

webapp填坑记录[更新中]

解决spring-boot启动中碰到的问题:Cannot determine embedded database driver class for database type NONE(转)(代码片段