zoukankan      html  css  js  c++  java
  • MySQL

    MySQL数据库

    一、基本知识

    sql语句

    分组查询: select * from table group by + 字段; --合并字段中重复的数据

    having:通常与group by连用,对分组的结果集进行再筛选

    order by:排序,默认升序ASC ,降序DESC

    三范式

    1NF:数据库中所有的字段都不可再分解

    2NF:在第1NF的基础上,每一列都要和主键有关联,即一张表只能有一种数据

    3NF:在第2NF的基础上,可以和另外一张表建立一个外键对应关系


    char 和 varchar 的区别

    char长度不可变 ---varchar长度可变、存放的字符比char多


    内连接、右连接、左连接

    内连接:就是普通连接,只显示两张表中有关联的数据【显示交集】

    inner join ...on.. 一般用 , where...

    左连接:以form左边为主,右表中没有的就显示null

    left join ... on

    右连接:以form右边为主,左表中没有的就显示null

    right join ... on


    mysql常用引擎

    1. InnoDB存储的文件有两个:表的定义文件 、数据文件

    2. MyiSAM存储的文件有三个:表的定义文件、数据文件、索引文件(保存了数据文件的指针)

      区别:

      1. InnoDB支持事务和外键,MyiSAM不支持
      2. InnoDB是聚集索引,MyiSAM是非聚集索引(数据文件和索引文件分开的),InnoDB

    优化sql的步骤

    1. 查看sql执行频率

      • show status like 'Com____'; 查询当前连接的信息

      • show global status like 'Com____'; 查询整个数据库总的连接信息

      • show global status like 'Innodb_row_%'; 查询Innodb

    2. 定位低效执行的sql

    3. 分析sql的执行计划

      • explain(解释)分析sql的执行计划

        ​ explain + sql语句;

      • mysql5.0.37提供了,show profile(分析)分析sql的执行计划

        ​ select @@have_profiling; 查看当前数据库是否支持profile;

        ​ set profiling = 1; 设置为1,开启profiling,默认是关闭的;

        ​ show profiles;

    	show profile for query 1/2/3...;  (可以查看详细的执行结果)
    
    - mysql5.6提供了,trace分析优化器执行计划
    
    	​	set optimizer_trace = 'enable=on', end marks_in_json=on;  设置格式为json
    
    	​	set potimizer_trace_max_mem_size=1000000;		设置trace能够使用的最大内存
    
    	​	执行sql语句
    
    	​	最后检查 information_schema.optimizer_trace就可以知道mysql如何执行sql语句的:
    
    	​		select * from information_schema.optimizer_traceG;
    

    --- 如何定位低效率执行的sql

    1. 通过慢查询日志定位

    2. 使用show processlist命令,可以实时查看sql的执行情况

    --- explain分析sql的执行计划

    字段 含义
    id 选择标识符,id值越大优先级越高,越先被执行;id如果相同,可以认为是一组,从上往下顺序执行
    select_type (1) SIMPLE(简单SELECT,不使用UNION或子查询等) (2) PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY) (3) UNION(UNION中的第二个或后面的SELECT语句) (4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询) (5) UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select) (6) SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询) (7) DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询) (8) DERIVED(派生表的SELECT, FROM子句的子查询) (9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)
    table 表名
    type 表的连接类型【ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)】
    possible_key 查询时可能使用到的索引
    key 实际使用到的索引
    key_len 索引字段的长度
    ref 表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
    rows 扫描行的数量
    extra 执行情况的说明和描述

    二、索引及sql优化策略

    1.索引(index)

    创建索引:create index 索引名 on 表名(列名)

    alter 添加索引:alter table 表名 add index / 普通索引

    ​ unique / 唯一索引

    ​ fulltext / 索引名(列名) 全文索引

    2.添加主键索引:alter table 表名 add primary key(列名)

    查看索引:show index from 表名

    索引分类:

    1. 普通索引:一个索引只包含单个列,一个表可以有多个单列索引

    2. 唯一索引:索引列的值唯一,允许有NULL值

    3. 主键索引

    4. 全文索引

    5. 组合索引:一个索引包含多个列

    • 优点:索引可以实现高效查询

    • 缺点:

      • 创建和维护索引要耗费更多的时间,降低了表的更新速度
      • 占用物理空间
    • 什么时候建立索引:对查询频率高、数据量大的表建立索引

    • 对适合的字段创建索引:1.经常查询的列 2.主键的列 3.外键的列 4.经常排序的列 5.使用在where子句中的列

    • 索引优化:

      • 索引不会包含有空(NULL)值的行列:创建数据库时不要让表的字段默认为空
      • 使用短索引:对串列进行索引,如果多数值是唯一的,就不要对整个列进行索引,指定一个长度进行短索引
      • like语句操作:like '%xx%'不使用索引,like'xx%'使用索引
      • 不要在列上进行运算:会导致索引失效,而进行全表扫描

      索引总结:mysql只针对以下操作符才使用索引:<,<=,>,>=,between in,以及某些时候的like。每张表创建的索引最好不要超过6个,最多可以创建16个索引,除非数据量真的非常多

    2.B-Tree索引

    索引节点都按照平衡树的数据结构来存储,减少定位记录的时间,加快存储速度

    B-Tree每个节点包含:

    1. 关键字和关键字的个数
    2. 指向父节点的指针、指向子节点的指针

    B-Tree特性:

    1. 关键字集合分布在整棵树中
    2. 任何关键字只出现在一个节点中
    3. 搜索可能在非叶子节点结束
    4. 搜索性能等价于在在关键字全集内做一次二分查找
    5. 自动实现层次控制,保证深度尽可能小,广度尽可能大

    3.全文索引

    存储结构是B-Tree,全文索引解决了模糊查询效率低的问题。(全文索引从左往右排序,like ‘xx%’)

    4.sql常见的优化策略

    1. 对查询进行优化、避免全表扫描:在where ,order by涉及的列上建立索引

    2. 避免在where子句中进行null值的判断,避免在where子句中使用!=,>,<:否则会导致索引失效,进行全表扫描

    3. 不使用or 来连接条件语句:否则会导致索引失效,进行全表扫描

      避免:select id from table where num=10 or num=20

      使用:select id from table where num=10

      ​ union all

      ​ select id from table where num=20

      4.避免在条件语句中对字段进行计算:num/2=100 改为:num=100*2;

      5.组合索引的使用:使用索引字段作为条件时,如果是复合索引,必须保证使用到该索引中的第一个字段作为条件,并且尽可能的让字段顺序与索引顺序一致。

      6.使用exists代替in:

      避免:select id from tableA where id in(select id from tableB)

      使用:select id from tableA where id exists(select id from tableB where id=tableA.id)

      7.不要使用 select * 号 ,用具体的字段列表代替" * ",不要返回用不到的字段,提高查询效率

    5.BTree与B+Tree的区别

    1. B-Tree:每个节点都存储key和data,叶子节点指针为空(NULL)
    2. B+Tree:只有叶子节点存储了data,叶子节点包含了这棵树所有的键值对,mysql在原B+树的基础上增加了一个指向相邻叶子节点的链表指针,提高了区间的访问性能

    三、视图(view)

    1.概述

    视图:是一种虚拟表,实际不存在。

    用途:用来封装多表查询的结果集,简化查询操作

    优点:视图相对于普通表的优势

    1. 简单:封装了多表查询的结果集,查询更简单
    2. 安全:用户只能访问被允许查询的结果集
    3. 数据独立:一旦视图的结构确定,原表增加列对视图没有影响;原表修改列名也可以通过

    2.创建、查询、修改、删除

    1. 创建:create view 视图名 as 跟查询语句

    2. 修改:alter view 视图名 as 跟查询语句

    3. 查询:show tables

    ​ select * from view_name

    1. 删除:drop view view_name

    四、存储过程和函数(procedure)

    1.概述

    存储过程 (procedure) 和函数 (function) :

    ​ 存储在数据库中的一段SQL语句的集合,减少数据在数据库和服务器之间的传输,提高了查询效率

    存储过程和函数的区别:函数必须有返回值,存储过程没有

    存储函数:是一个有返回值的过程

    2.存储过程

    1.创建:

    create procedure procedure_name()
    begin
    	--sql语句
    	--sql语句 
    end ;
    
    改变分隔符:delimter $;
    

    2.调用存储过程 :

    -- call procedure_name();
    

    3.查询:

    1.查询存储过程的状态信息:
      -- show procedure status
    2.查询一个数据库中的所有存储过程: 
    	select name from mysql.proc where db='database_name';  
    

    4.删除

    -- drop procedure procedure_name 
    

    5.游标/光标

    ​ 存储查询结果集的数据类型,在存储过程和函数中可以使用游标对结果集进行循环的处理。 游标的使用包括:声明、open、fetch、close

    ​ create procedure pro_name()

    ​ begin

    1. 声明光标:declare cur_name cursor for select 语句 ;
    2. open光标:open cur_name ;
    3. fetch光标:fetch cur_name into 查询的字段
    4. close光标:
    

    ​ end

    循环获取游标

    create procedure pro_name()
    begin
    declare e_id int(10);
    declare e_name varchar(10);
    declare hasdata int default 1;
    --声明游标
    	   declare e_city cursor for select id,cityname from city;
    固定语法: declare exit handler for not found set hasdata=0;
    --打开游标
    open e_city;
    
    repeat
    fetch e_city into e_id,e_name;
    select concat('id=',e_id,'cityname=',e_name);
    until hasdata=0
    end repeat;
    
    close e_city;
    end $
    

    3..储存函数

    语法结构:创建存储函数

    create function function_name()
    returns type
    begin
    	--sql语句
    end 
    

    查询:select function_name();

    删除:drop function function_name;

    五、触发器(trigger)

    1.概述

    ​ 触发器是与表有关的数据库对象,指的是在增、删、改之前或之后,触发并且执行SQL语句集合

    ​ 触发器可以用来协助应用在数据库端确保数据的完整性,日志记录,数据校验等操作。使用别名 NEW 和 OLD 来引用触发器中发生变化的记录内容

    ​ MySQL只支持行级触发,不支持语句级触发。

    触发器类型 NEW和OLD的使用
    INSERT 类型触发器 NEW表示将要或者已经新增的数据
    UPDATE类型触发器 OLD表示修改前的数据,NEW表示将要或者已经修改后的数据
    DELETE类型触发器 OLD表示将要或者已经删除的数据

    2.创建触发器

    create trigger trigger_name;
    before/after insert/update/delete
    on table_name
    [for each row]  --行级触发器
    begin
    trigger_stmt;
    end;
    
  • 相关阅读:
    slf4j绑定log4j失败
    [转]activiti5用户任务分配
    关于ajax提交的公共接口的一大用处
    jQuery插件开发方式
    centos7安装mysql
    Centos7安装JDK
    奇葩问题:spring+mybaits项目突然出现其中一些Mapper类找不到
    JAVA多线程下,获取递增的序列号
    库存扣减的流水账记录问题
    My97DatePicker使用的问题
  • 原文地址:https://www.cnblogs.com/qqkkOvO/p/14071684.html
Copyright © 2011-2022 走看看