MYSQL使用总结

一,mysql安装卸载

安装卸载:mysql安装和卸载

二,SQLyog 下载 中文版 破解版 注册码

参考:SQLyog 下载 中文版 破解版 注册码
参考:SQLyog图形化l数据库的操作和学习

三,mysql语句及优化

1.mysql和oracle大致相同,下面回忆一些不同的地方

mysql基础语句参考oracle链接:Oracle使用总结
1.mysql使用limit分页,limit(x,y) 从第x行开始,截取y行,数据库默认从0开始。
oracle使用rownum

--mysql
select * from table limit 0, 10
--oracle
select * from (select * ,rownum as rn from table) where rn <= 10

2.多条件判断,case使用

--mysql
SELECT 
CASE id 
  WHEN 1 THEN id
  WHEN 3 THEN NAME
  ELSE id
END
FROM task_work
--oracle 除了有case when还有简写方式的decode
-- 行列转换
SELECT ID,NAME,
	SUM(DECODE(course,'语文',score,0)) 语文,
	SUM(DECODE(course,'数学',score,0)) 数学,
	SUM(DECODE(course,'英语',score,0)) 英语,
	SUM(DECODE(course,'历史',score,0)) 历史,
	SUM(DECODE(course,'化学',score,0)) 化学
FROM kecheng
GROUP BY ID ,NAME

2.函数使用

-- 格式化时间,字符串转时间
date_format(date,'%Y-%m-%d'); 
str_to_date(date,'%Y-%m-%d');
-- substr使用方法不同, oracle 从0 开始,  mysql 从1  

-- 空概念
oracle 的空和mysql的空不是同样的概念
oracle ''等同于null, mysql '' 不等同于null

4.主键自增
Mysql可以给表主键设置自增,添加数据时不需要设置id,数据库会自动设置id;
Oracle没有主键自增,如果需要设置自增,需要给表添加自增序列;
添加数据时,从序列中取下一个值作为id;

5.分组排序
MySql的group by与oracle有所不同,查询得字段可以不用写聚合函数,查询结果取得是每一组的第一行记录。group by默认按id升序,mysql5.7以及以后在子查询内部 使用order by 可能会被忽略。

2.mysql优化

1.mysql的架构 见图
2.mysql存储引擎

MyISAM:
	不支持事务
	表锁
	不支持外键
	支持表压缩
		.frm:表结构
		.MYD:数据
		.MYI:索引	
InnoDB: 
	事务
	行级锁
		.frm:表结构
		.ibd:数据和索引

show engines:查看支持的引擎
show table status like 表名\G

  1. mysql支持的数据类型
    Int(tinyint微整形(1字节),smallint(2),mediumint(3),int(4),bigint(8))
    decimal
    float,double
    char varchar
    text, blob
    date,time,datetime timestamp

4.create table a like b;//以b建一张空表
锁:读锁、写锁
lock tables 表名(read | write)
unlock tables;

5、mysql中的日志文件
1、错误日志文件,默认文件hostname.err 可以自己定义
[mysqld_safe]
Log-error=/var/log/mysqld.log
2、通用日志文件 :将所有的查询语句都会记录下来
注意:这个文件一般都是关闭的,只是需要记录时候才打开。
3、慢查询日志文件
需要慢查询打开:什么才叫慢?实质上自己可以定义
比如我定义查询时间大于3秒的就慢查询
会将查询时间大于3秒这些查询语句提取出来写慢查询日志中
我就可以分析该语句有什么问题及优化点
Slow_query_log=on|off --是否开启慢查询日志
Slow_query_log_file=路径+文件名–指定慢查询日志保存的路径和文件名,如果不指定默认是在存放数据文件的目录下名称为hostname-slow.log的文件名
long_query_time=2–指定多少秒未返回结果的语句为慢查询
Long-queries-not-using-indexes–记录所有没有使用到索引的查询语句
Min_examined_row_limit=1000–记录那些查找了多余1000次而引发的慢查询
Log-slow-admin-statements–记录那些慢的optimize table,analyze table和alter table的语句
Log-slow-slave-statements–记录由slave所产生的慢查询

8、执行计划的查看

1、使用explain可以看执行计划
对执行计划的属性说明
 	 select_type:查询的类型
     simple:不含有子查询
	 primary:含子查询
	 subquery:非from子查询
	 derived:from型子查询
	 union
2、possible_key: 可能用到的索引
3、key : 最终用的索引.
4、key_len: 使用的索引的最大长度
5、type列: 是指查询的方式。
    type=all(全表扫描)
	type=index
	type=range 使用索引做范围扫描
	type=ref   直接就使用索引就可以了
	type=const 按主键或者唯一键查询
	
6、rows :估计要扫描的记录数
7、extra = index:是指用到了索引覆盖,效率非常高
   extra = using where:是指光靠索引定位不了,还得where判断一下 
   extra = using temporary:是指用上了临时表, group by 与 order by 不同列时,或group by ,order by 别的表的列.
   extra = using filesort:文件排序(文件可能在磁盘,也可能在内存)

总结:工作中就是不断的看执行计划,效率不对,就各种的变化sql写法

四,MySql基础

1.MySql 数据类型

1.1字符串类型

参考:mysql的char,varchar,text类型的区别总结
参考:MySQL性能优化之char、varchar、text的区别
MySQL5.0以上的VARCHAR(n)可存储中文字符和英文字符数是一致的,都是n个字符

MySQL规定:单个字段长度不能超过 65535 bytes(所有字符串类型字段包括其字段名称占用空间都计算在内, text、blob等大字段类型除外)。
编码为utf-8时,VARCHAR,TEXT最大长度是21844


总结:

  • 存储定长字符串,尽量用char,索引速度极快。
  • 长度255以上字符串,只能用varchar和text。
  • 能用varchar就不要用text。
  • text和blob不能设置默认值。

参考:MySQL TEXT数据类型的最大长度
TEXT:只能存储字符数据;包括tinytext mediumtext longtext
BLOB:用于存储二进制数据,比如照片、声音和视频;包括tinyblob longblob mediumblob
tinyblob,tinytext,最大存储为 256 bytes
blob,text,最大存储约 64kb
mediumblob,mediumtext,最大存储约 16MB
longblob,longtext,最大存储约 4GB

1.2 数值类型

无符号unsigned表示设置的数据为0或正数;有符号可以是负数;
参考:MySQL 数据类型
TINYINT: 大小1byte,有符号范围(-128,127) ,无符号范围(0,255)
SMALLINT:大小2bytes,有符号范围(-32 768,32 767),无符号范围(0,65 535)
MEDIUMINT:大小3bytes,有符号范围(-8 388 608,8 388 607),无符号范围(0,16 777 215)
INT:大小4bytes,有符号范围(-2 147 483 648,2 147 483 647),无符号范围(0,4 294 967 295)
BIGINT:大小8bytes,有符号范围(-9,223,372,036,854,775,808,9 223 372 036 854 775 807)

FLOAT:单精度浮点数,大小4bytes,Float(10,2):整数部分为8位,小数部分为2位
DOUBLE: 双精度浮点数,大小8bytes
DECIMAL:定点型小数,适合财务和货币计算的128位数据类型
小数类型:浮点型和定点型,float和double都是浮点型,而decimal是定点型;
MySQL浮点型和定点型可以用类型名称后加(M,D)来表示,M表示该值的总共长度,D表示小数点后面的长度,M和D又称为精度和标度,如float(5,2)的 可显示为999.99,MySQL保存值时会进行四舍五入,如果插入999.009,则结果为999.01。
浮点型又称为精度类型:是一种有可能丢失精度的数据类型,数据有可能不那么准确(由其是在超出范围的时候)
Float单精度类型:只能保证大概7个左右的精度(如果数据在7位数以内,那么基本是准确的,但是如果超过7位数,那么就是不准确的)
Double又称之为双精度:系统用8个字节来存储数据,表示的范围更大,10^308次方,但是精度也只有15位左右。

参考:mysql中float、double、decimal的区别
参考:mysql列类型二——小数类型(float,double,decimal)

1.3日期和时间类型

DATE:大小3字节,范围:1000-01-01/9999-12-31,格式:YYYY-MM-DD
TIME:大小3字节,范围:’-838:59:59’/‘838:59:59’,格式:HH:MM:SS
YEAR:大小1字节,范围:1901/2155,格式:YYYY
DATETIME:大小8字节,范围:1000-01-01 00:00:00/9999-12-31 23:59:59,格式:YYYY-MM-DD HH:MM:SS
TIMESTAMP:大小4字节,范围 ‘1970-01-01 00:00:01.000000’ to '2038-01-19 03:14:07.999999’的时间戳,
TIMESTAMP类型有专有的自动更新特性,字段默认设置 current_timestamp,即可自动更新时间

2.MySQL 函数

2.1字符串函数

LENGTH(s) 获取字符串的长度
CHAR_LENGTH(s) 返回字符串 s 的字符数
CONCAT(s1,s2…sn) 字符串 s1,s2 等多个字符串合并为一个字符串
CONCAT_WS(x, s1,s2…sn) 同 CONCAT(s1,s2,…) 函数,每个字符串以x 作为分隔符

FORMAT(x,n) 函数可以将数字 x 进行格式化 “#,###.##”, 将 x 保留到小数点后 n 位,最后一位四舍五入。
LOCATE(s1,s) 从字符串 s 中获取 s1 的开始位置
LEFT(s,n) 返回字符串 s 的前 n 个字符
RIGHT(s,n) 返回字符串 s 的后 n 个字符

SUBSTR起始下标:oracle 从0 开始,mysql 从1开始
SUBSTR(s, start, length) 从字符串 s 的 start 位置截取长度为 length 的子字符串
SUBSTRING(s, start, length) , SUBSTR() 等价于 SUBSTRING() 函数

UPPER(s) 将字符串转换为大写
TRIM(s) 去掉字符串 s 开始和结尾处的空格

substring_index,参考:mysql函数substring_index的用法
CONVERT(value, type);,参考:MySQL CAST与CONVERT 函数的用法
REPEAT(‘ab’,2),'ab’表示要复制的字符串,2表示复制的份数

2.2聚合函数

sum,avg,max,min,count,聚合函数不统计值为null的行,我们可以通过distinct过滤掉重复的记录,也可以通过group by 分组。
Count([Column Name])函数不统计带有 Null 字段的记录,除非使用星号,Count 将计算所有记录的总量,包括有 Null 的字段的记录。Count(*) 比 Count ([Column Name]) 快得多。不要将星号放在引号 (’ ') 中。

SUM(expression) 返回指定字段的总和
AVG(expression) 返回一个表达式的平均值,expression 是一个字段
MAX(expression) 返回字段 expression 中的最大值
MIN(expression) 返回字段 expression 中的最小值
COUNT(expression) 返回查询的记录总数,expression 参数是一个字段或者 * 号

2.3日期函数

NOW() 返回当前日期和时间 2018-09-19 20:57:43
CURRENT_DATE() 返回当前日期 2018-09-19

CURRENT_TIME 返回当前时间 9:59:02
CURRENT_TIMESTAMP() 返回当前时间戳
DATE_FORMAT(d,f) 按表达式 f 的要求显示日期 d
SELECT DATE_FORMAT(‘2011-11-11 11:11:11’, ‘%Y-%m-%d %r’)
-> 2011-11-11 11:11:11 AM

DAY(d) 返回日期值 d 的日期部分 天的号数
HOUR(t) 返回 t 中的小时值
MINUTE(t) 返回 t 中的分钟值
DAYOFWEEK(d) 日期 d 今天是星期几,1 星期日,2 星期一,以此类推
时间与字符串相互转换
date_format(now(), ‘%Y-%m-%d’); 格式化日期
str_to_date(‘2016-01-02’, ‘%Y-%m-%d %H’); 字符串转时间

MySQL日期格式化(format)取值范围。
%Y 四位数字表示的年份(2015,2016…)
%y 两位数字表示的年份(15,16…)
%m 两位数字表示月份(01,02, …,12)
%d 两位数字表示月中天数(01,02, …,31)
%H 24小时制,两位数形式小时(00,01, …,23)
%I、%i 两位数字形式的分( 00,01, …, 59)
%S、%s 两位数字形式的秒( 00,01, …, 59)
% 文字 直接输出文字内容
常用标准格式%Y-%m-%d %H:%i:%s
SELECT DATE_FORMAT(NOW(), ‘%Y-%m-%d %H:%i:%s’)

UNIX_TIMESTAMP(),返回自’1970-01-01 00:00:00’的到当前时间的秒数差
UNIX_TIMESTAMP(date),返回自’1970-01-01 00:00:00’与指定时间的秒数差

2.4高级函数

IF(expr,v1,v2) 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。
IFNULL(v1,v2) 如果 v1 的值不为 NULL,则返回 v1,否则返回 v2。
ISNULL(expression) 判断表达式是否为 NULL

参考:MYSQL中 datediff、timestampdiff函数的使用
DATEDIFF(date1,date2),返回两个日期之间的天数
TIMESTAMPDIFF(interval,datetime1,datetime2),以interval为单位,计算日期datetime2-datetime1的差值

参考:Mysql to_days()用法
TO_DAYS(),返回从0000年(公元1年)至当前日期的总天数。
获取昨天的数据
SELECT * FROM hx_volunteer_service_sched_record WHERE TO_DAYS(NOW()) - TO_DAYS(createTime) <= 1

参考:mysql中的instr()函数的用法
INSTR(str,substr),返回 子字符串substr 在 字符串str 中首次出现的位置;instr()函数不区分大小写,位置是从1开始,如没找到则返回0
在没有索引的情况下,instr()函数与like运算符的速度是一样的;在具有前缀搜索的LIKE运算符下,使用like运算符速度会更快一些

GROUP_CONCAT(),参考:浅析MySQL中concat以及group_concat的使用
1、功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。
2、语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator ‘分隔符’] )
说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator是一个字符串值,缺省为一个逗号。

3.开发经验

3.1字段升序时,NULL排在最后

ORDER BY将字段降序时,字段为NULL的数据会排在最后面
ORDER BY将字段升序时,字段为NULL的数据会排在最前面,使用ORDER BY status IS NULL,status
SELECT * FROM organ_coip_situation ORDER BY status IS NULL,status

参考:mysql排序字段为空的排在最后面

3.2 SELECT DISTINCT 语句

SELECT DISTINCT d, f FROM test
DISTINCT必须放在开头,仅返回去重后列后的数据,如果要返回其他列用group by去重
单列去重:相同列的值只保留1个。
多列去重:只有所有指定的列信息都相同,才会被认为是重复的信息。

参考:去重是distinct还是group by?
参考:sql去重复操作详解SQL中distinct的用法

3.3 group by 对多个字段进行分组

参考:mysql group by 对多个字段进行分组
GROUP BY X意思是将所有具有相同X字段值的记录放到一个分组里。
GROUP BY X, Y意思是将所有具有相同X字段值和Y字段值的记录放到一个分组里。
然后对每个分组中的数据应用聚合函数

3.4mysql插入重复问题

主键是唯一的索引,当表中有多个主键时,称为复合主键,复合主键联合保证唯一索引”。
参考:数据库为何要有复合主键(多主键)

参考:mysql数据库中避免重复数据插入

前提:表中必须要有Unique索引,即主键或唯一键。
INSERT IGNORE INTO 如果Unique索引的字段已存在,则忽略本次新增
ON DUPLICATE KEY UPDATE 如果Unique索引的字段已存在,则执行后面的UPDATE语句,原Unique索引的字段也可修改

在这里插入图片描述

-- 如果Unique索引的字段已存在【id或phone】,则忽略本次新增
INSERT IGNORE INTO `test`(id, phone ,`name`)
VALUES('T001', '16608349001', '姓名');

-- 测试存在id
INSERT IGNORE INTO `test`(id, phone ,`name`)
VALUES('T001', '1111', '测试存在id');
-- 测试存在phone
INSERT IGNORE INTO `test`(id, phone ,`name`)
VALUES('1111', '16608349001', '测试存在phone');

-- 如果Unique索引的字段已存在【id或phone】,则执行后面的UPDATE语句,原Unique索引的字段也可修改
-- 测试存在id,此时会拿主键id作为唯一索引去UPDATE
INSERT INTO `test`(id, phone ,`name`)
VALUES('T001', '1111', '姓名')
ON DUPLICATE KEY UPDATE id='2222', phone='2222', `name`='测试存在id';

-- 测试存在phone,此时会拿唯一键phone作为唯一索引去UPDATE
INSERT INTO `test`(id, phone ,`name`)
VALUES('1111', '16608349001', '姓名')
ON DUPLICATE KEY UPDATE id='2222', phone='2222', `name`='测试存在phone';

3.5 关于 left join的优化

参考:mysql的left join和inner join的效率对比,以及如何优化

1、left join选择小表作为驱动表(这部分基本是大家的共识)

2、如果左表比较大,并且业务要求驱动表必须是左表,那么我们可以通过where条件语句,使得左表被过滤的小一些,主要原理和第一条类似

3、关联字段给索引,因为在mysql的嵌套循环算法中,是通过关联字段进行关联,并查询的,所以给关联字段索引很必要

4、如果sql里面有排序,请给排序字段加上索引,不然会造成排序使用全表扫描
		参考:https://www.oschina.net/question/930697_2190172
		
5、如果where条件中含有右表的非空条件(除开is null),则left join语句等同于join语句,可直接改写成join语句。 

6、根据文档,MySQL能更高效地在声明具有相同类型和尺寸的列上使用索引。所以把表与表之间的关联字段给上encoding和collation(决定字符比较的规则)全部改成统一的类型

7、右表的条件列一定要加上索引(主键、唯一索引、前缀索引等),最好能够使type达到range及以上(ref,eq_ref,const,system) 

3.6 in与not in,exists与not exists的区别以及性能分析

参考:SQL 子查询 EXISTS 和 NOT EXISTS

MySQL EXISTS 和 NOT EXISTS 子查询语法如下:
SELECT … FROM table WHERE EXISTS (subquery)
该语法可以理解为:将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUE 或 FALSE)来决定主查询的数据结果是否得以保留。

带有EXISTS 和 NOT EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或者逻辑假值“false”。

exists 和 in
如果查询的两个表大小相当,那么用in和exists差别不大;如果两个表中一个较小一个较大,则子查询表大的用exists,子查询表小的用in;外表大,用IN;内表大,用EXISTS。
not exists 和 not in
如果查询语句使用了not in,那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。

参考:浅谈sql中的in与not in,exists与not exists的区别以及性能分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值