区别系列
- mysql 空值(null)和空字符(' ')的区别
- IFNULL()、 ISNULL()、NULLIF()、COALESCE()、IF()函数的区别
- [Select count(*)、Count(1)、Count(0)的区别和执行效率比较]()
- MySQL中date和datetime的区别
- union /union all
- MySQL中存储日期字段Timestamp和Datetime的区别
mysql 空值(null)和空字符(’ ')的区别
网址推荐1网址推荐2 空字符(’’)和空值(null)表面上看都是空,其实存在一些差异:
概念上的不同:1、空值不占空间 2、null值占空间。
空值(NULL) 的 长度是NULL,不确定占用了多少存储空间,但是占用存储空间 的
空字符串(‘’)的长度是0,是不占用空间 的
区别:
在进行count()统计某列时候,如果用null值系统会自动忽略掉,但是空字符会进行统计。
不过count(*)会被优化,直接返回总行数,包括null值。
判断null用is null或is not null,SQL可以使用ifnull()函数进行处理;判断空字符用=''或者!=''进行处理。
null和''的查询方式不同。而且比较字符 ‘=’’>’ ‘<’ ‘<>’不能用于查询null,
如果需要查询空值(null),需使用is null 和is not null。
空值(null)不能参与任何计算,因为空值参与任何计算都为空。
如果非要参与计算,需使用ifnull函数,将null转换为''才能正常计算。
当统计数量的时候。空值(null)并不会被当成有效值去统计。
同理,sum()求和的时候,null也不会被统计进来,这样就能理解,
为什么null计算的时候结果为空,而sum()求和的时候结果正常了。
对于timestamp数据类型,插入null值会是当前系统时间;插入空字符,则出现0000-00-00 00:00:00
定义为NOT NULL的字段只能插入空值,不能插入null值,而NULL字段可以插入空值,也可以插入null值。
可以发现 is not null 只会过滤为null值的列,而<>会同时过滤空值和null值,
所以要根据实际情况选择过滤方式。另外,判断null值只能用 is null 或 is not null ,不能用 = 或 <>。
当使用ORDER BY时,首先呈现NULL值。如果你用DESC以降序排序,NULL值最后显示。
当使用GROUP BY时,所有的NULL值被认为是相等的,故只显示一行。
结论:
所以在设置默认值的时候,尽量不要用null当默认值,如果字段是int类型,默认为0;如果是varchar类型,默认值用空字符串(’’)会更好一些。带有null的默认值还是可以走索引的,只是会影响效率。当然,如果确认该字段不会用到索引的话,也是可以设置为null的。
在设置字段的时候,可以给字段设置为 not null ,因为 not null 这个概念和默认值是不冲突的。我们在设置默认值为(’’)的时候,虽然避免了null的情况,但是可能存在直接给字段赋值为null,这样数据库中还是会出现null的情况,所以强烈建议都给字段加上 not null。
如果 判断符号左右两边有一个为NULL,结果就是null,除非使用安全的等值判断 <=>
select null = null; -- null(空)
select null = 4; -- null(空)
select 4 = null; -- null(空)
select null != 1; -- null(空)
select null <=> null; -- 1
select 1 + null;-- null(空)
select "1" + null;-- null(空)
select 3 + IFNULL(null,2);-- 5
IFNULL()、 ISNULL()、NULLIF()、COALESCE()、IF()函数的区别
推荐网址关于mysql中的null须知:
在MySQL中,NULL值表示一个未知值,它不同于0或空字符串’',并且不等于它自身。
我们如果将NULL值与另一个NULL值或任何其他值进行比较,则结果为NULL,因为一个不知道是什么的值(NULL值)与另一个不知道是什么的值(NULL值)比较,其值当然也是一个不知道是什么的值(NULL值)。
然而我们通常,使用NULL值来表示数据丢失,未知或不适用的情况。 例如,潜在客户的电话号码可能为NULL,并且可以稍后添加。所以我们创建表时,可以通过使用NOT NULL约束来指定列是否接受NULL值。
创建表的时候可以通过使用NOT NULL约束来指定列是否接受NULL值。
可以在insert语句中使用NULL值来指定数据丢失。
如果我们要将列的值设置为NULL,可以使用赋值运算符(=)。
UPDATE leads SET phone = NULL WHERE id = 3;
如果使用order by子句按升序对结果集进行排序,则 MySQL认为NULL值低于其他值, 因此,它会首先显示NULL值。
使用ORDER BY DESC,NULL值将显示在结果集的最后。
在查询中测试NULL,可以在where子句中使用IS NULL或IS NOT NULL运算符。
还可以使用IS NOT运算符来获取所有提供电子邮件地址的潜在客户:
SELECT * FROM leads WHERE email IS NOT NULL;
即使NULL不等于NULL,GROUP BY子句中视两个NULL值相等
在列上使用唯一约束或UNIQUE索引时,可以在该列中插入多个NULL值,在这种情况下,MySQL认为NULL值是不同的。
这里我们要注意,如果使用BDB存储引擎的话,mysql会认为NULL值相等,因此我们不能将多个NULL值插入到具有唯一约束的列中。
一、IFNULL(expr1,expr2)用法
假如expr1不为NULL,则 IFNULL() 的返回值为expr1; 否则其返回值为 expr2。IFNULL()的返回值是数字或是字符串,具体情况取决于其所使用的语境。
二、ISNULL(expr) 的用法
如expr 为null,那么isnull() 的返回值为 1,否则返回值为 0。
三、NULLIF(expr1,expr2)用法
如果expr1 = expr2 成立,那么返回值为NULL,否则返回值为expr1。这和CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END相同。
四、COALESCE()函数, 它接受参数列表,并返回第一个非NULL参数。
五、IF()函数的使用
IF(expr1,expr2,expr3),如果expr1表达式的值为true,则返回expr2的值,如果expr1表达式的值为false,则返回expr3的值。
expr1 <> 0 以及 expr1 <> NULL以及用trim后正负数值开头才会为true
# 以下全 no
select IF(null,'yes','no'); -- no
select IF('','yes','no'); -- no
select IF(' ','yes','no'); -- no
select IF(0,'yes','no'); -- no
select IF(' ff','yes','no'); -- no
select IF('ff','yes','no'); -- no
select IF('-','yes','no'); -- no
select IF('f1f','yes','no'); -- no
# 只有数字开头包括负数包括前面有空格 才会为true
select IF('1','yes','no'); -- yes
select IF('1f','yes','no');-- yes
select IF('-1f','yes','no');-- yes
select IF(' -1f','yes','no');-- yes
# 字符才有ASCII 虽然你写个字符串 但是只是第一个生效
select ASCII(null); -- null
select ASCII(''); -- 0
select ASCII(' '); -- 32
select ASCII(' '); -- 32
select ASCII(' fffA'),ASCII(' A'),ASCII(' dffggg') -- 全32
select ASCII('dffggg'),ASCII('d '),ASCII('dfffgg'); -- 全100
select IF(ASCII(null),'yes','no'); -- no
select IF(ASCII(''),'yes','no'); -- no
select IF( ASCII(' '),'yes','no'); -- yes
select IF(ASCII(' ff'),'yes','no'); -- yes
Select count(*)、Count(1)、Count(0)的区别和执行效率比较
这个众说纷纭,这个东西脱离了条件,都是在耍流氓,还需要考虑搜索引擎啥的,索引啥的都会有影响。
count()和count(1)执行的效率是完全一样的。
count()的执行效率比count(col)高,因此可以用count()的时候就不要去用count(col)。
count(col)的执行效率比count(distinct col)高,不过这个结论的意义不大,这两种方法也是看需要去用。
如果是对特定的列做count的话建立这个列的非聚集索引能对count有很大的帮助。
如果经常count()的话则可以找一个最小的col建立非聚集索引以避免全表扫描而影响整体性能。
在不加WHERE限制条件的情况下,COUNT()与COUNT(COL)基本可以认为是等价的;
但是在有WHERE限制条件的情况下,COUNT()会比COUNT(COL)快非常多;
count(0)=count(1)=count(*)
- count(指定的有效值)–执行计划都会转化为count(*)
- 如果指定的是列名,会判断是否有null,null不计算
当然,在建立优化count的索引之前一定要考虑新建立的索引会不会对别的查询有影响,影响有多大,要充分考虑之后再决定是否要这个索引,这是很重要的一点,不要捡了芝麻丢了西瓜。
还有这个说法:
1、count(*)、count(1):
count()对行的数目进行计算,包含NULL,count(1)这个用法和count()的结果是一样的。
如果表没有主键,那么count(1)比count()快。表有主键,count()会自动优化到主键列上。
如果表只有一个字段,count(*)最快。
count(1)跟count(主键)一样,只扫描主键。count(*)跟count(非主键)一样,扫描整个表。明显前者更快一些。
count(1)和count(*)基本没有差别,但在优化的时候尽量使用count(1)。
2、count(1)、count(列名):
(1) count(1) 会统计表中的所有的记录数,包含字段为null 的记录。
(2) count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即不统计字段为null 的记录。
MySQL中date和datetime的区别
区别1:应用场景的区别
①date类型可用于需要一个日期值而不需要时间部分时;
②datetime类型:可用于需要同时包含日期和时间信息的值。
区别2:显示格式的区别
①date:MySQL 以 'YYYY-MM-DD' 格式检索与显示date值;
②datetime:MySQL 以 'YYYY-MM-DD HH:mm:ss'格式检索与显示 DATETIME 类型。
区别3:显示范围的区别
①date类型:支持的范围是 '1000-01-01' 到'9999-12-31';
②datetime类型:支持的范围是'1000-01-0100:00:00' 到 '9999-12-3123:59:59'。
区别4:后台取值的区别
①Date后台取值:@JSONField(format=”yyyy-MM-dd”);
②DateTime后台取值:@JSONField(format=”yyyy-MM-dd HH:mm:ss:SSS”)(这里只会精确到秒)。
union /union all
union会自动将完全重复的数据去除掉,union all会保留那些重复的数据;
union语句注意事项:
1.通过union连接的SQL它们分别单独取出的列数必须相同;
2.不要求合并的表列名称相同时,以第一个sql 表列名为准;
3.使用union 时,完全相等的行,将会被合并,由于合并比较耗时,一般不直接使用 union 进行合并,而是通常采用union all 进行合并;
4.被union 连接的sql 子句,单个子句中不用写order by ,因为不会有排序的效果。但可以对最终的结果集进行排序;
# 没有排序效果
(select id,name from A order by id) union all (select id,name from B order by id);
# 有排序效果
(select id,name from A ) union all (select id,name from B ) order by id;
MySQL中存储日期字段Timestamp和Datetime的区别
首先说一下,日期字段类型尽量选用datetime
主要一是因为范围,二是因为时区
( 在使用mybatis-plus自带的插入和更新时,出现了一个神奇的问题,前台传入的是Date类型(yyyy-MM-dd),但是在插入的时候,却发现是Timestamp类型,插入到数据库发现时间比原来减少了8小时,后来将数据库日期类型修改为Datetime解决)
- 存储空间不同
a) TIMESTAMP占用4个字节
b) DATETIME占用8个字节 - 受时区影响
a) TIMESTAMP实际记录的是1970-01-01 00:00:01到现在的数数,受时区影响
b) DATETIME不受时区影响 - 时间范围不同
a) TIMESTAMP的时间范围是:‘1970-01-01 00:00:01’ UTC ~ ‘2038-01-19 03:14:07’ UTC
b) DATETIME的时间范围是:‘1000-01-01 00:00:00’ ~ ‘9999-12-31 23:59:59’ - 自动更新
a) TIMESTAMP类型在默认情况下,insert、update 数据时,TIMESTAMP列会自动以当前时间(CURRENT_TIMESTAMP)填充/更新。 - Mysql中,TIMESTAMP和long之间的转换函数:
a) TIMESTAMP转long:UNIX_TIMESTAMP
b) long转TIMESTAMP:FROM_UNIXTIME