mysql基础进阶

MySQL知识点

基础

MySQL在Linux下的安装配置

# 下载数据库
sudo apt-get install mysql-server-8.0

# 登录mysql并修改密码
mysql -uroot
mysql> use mysql;
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
mysql>flush privileges;
mysql> quit;

# 再次登录时需要需要输入密码
mysql  -uroot -p
  • 开启数据库远程连接

    mysql>use mysql;
    mysql>update user set host="%"where user="root";
    mysql>flush privileges;
    mysql> quit;
    

    其中host后面接的是主机IP,设置为通配符%表示所有的主机都可以连接。

  • 开放数据库端口

    # 查看端口的状态
    netstat -an | grep 3306
    
    vim /etc/mysql/mysql.conf.d/mysqld.cnf
    

    打开该文件后注释掉下面这行:

    bind-address            = 127.0.0.1
    

    重启mysql

    /etc/init.d/mysql restart
    

SQL

通用语法及分类
  • SQL通用语法

    1. SQL语句可与i单行活多行书写,以分号结尾
    2. SQL语句可以使用空格/缩进来增强语句的可读性
    3. MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。
    4. 注释:
      • 单行注释:-- 注释内容 或 #注释内容
      • 多行注释:/* 注释内容*/
  • SQL分类

    分类全称说明
    DDLData Definition Language数据定义语言,用来定义数据库对象(数据库,表,字段)
    DMLData Manipulation Language数据操作语言,用来对数据库中表的数据进行增删改
    DQLData Query Language数据查询语言,用来查询数据库中的表记录
    DCLData Control Language数据控制语言,用来创建数据库用户,控制数据库的访问权限
DDL数据库操作
  • 查询

    查询所有数据库

    show databases;
    

    查询当前数据库

    select DATABASE();
    
  • 创建

    creat database [if not exists] 数据库名 [default charset 字符集][collate 排序规则];
    
  • 删除

    drop database[if exists]数据库名;
    
  • 使用

    use 数据库名;
    
DDL表操作查询
  • 查询当前数据库所有表

    show tables;
    
  • 查询表结构

    DESC 表名;
    
  • 查询指定表的建表语句

    show create table 表名;
    
  • 创建表

    create table 表名(
    		字段1 字段1类型 [comment 字段1注释],
        	字段2 字段2类型 [comment 字段2注释],
        	字段3 字段3类型 [comment 字段3注释],
        	......
    )[comment 表注释];
    
DDL修改表和删除表
  • 添加字段

    alter table 表名 add 字段名 类型(长度)[comment 注释][约束];
    
  • 修改数据类型

    alter table 表名 modify 字段名 新数据类型(长度);
    
  • 修改字段名和字段类型

    alter table 表名 change 旧字段名 新字段名 类型(长度)[COMMENT 注释][约束];
    
  • 删除字段

    alter table 表名 drop 字段名;
    
  • 修改表名

    alter table 表名 rename to 新表名;
    
  • 删除表

    drop table [if exists] 表名;
    

    删除指定表,并重新创建该表(可以理解为清空这张表)。

    truncate table 表名;
    
DML语句插入、更新和删除
  • 插入(insert)

    insert into table_name(字段1,字段2....) values(值1,值2....);
    

    当给全部字段添加数据时,可以省略字段名:

    insert into table_name values(值1,值2....);
    

    第一种给指定字段添加数据,如果有字段未指定,默认数据为NULL,但是如果字段值不能为空的话,则插入失败。

    当批量添加数据时,可以在values后面跟多组数据:

    insert into table_name(字段1,字段2....) values(值1,值2....),(值1,值2....),(值1,值2....);
    insert into table_name values(值1,值2....),(值1,值2....),(值1,值2....);
    

    注意:

    • 插入数据时,指定字段顺序需要与值的顺序一一对应
    • 字符串和日期类型应该包含在引号中
    • 插入数据的大小应该在数据规定的范围内
  • 更新(update)

    update 表名 set 字段名1 = 值1,字段名2 = 值2 where 条件;
    

    需要注意的是,如果不加后面的where条件,那么这条语句是对表中某一个或几个字段所有数据进行更改,这是相当危险的操作。

  • 删除(delete)

    delete from table_name where 条件;
    

    和更新一样,如果不加条件是删除表的所有数据。在不开启事务的前提下,删除之后无法回滚,是一个很危险的操作。

    delete只能删除某一条或多条数据,不能删除某个字段的值,如果要删除某个字段的值,可以使用update将字段某个值置为NULL。

DQL语句(属于数据库使用最多的)
  • DQL基础语法

    select
    			字段列表
    from
    			表名列表
    where
    			条件列表
    group by
    			分组字段列表
    having
    			分组后条件列表
    order by
    			排序字段列表
    limit
    			分页参数
    
    1. 查询多个字段

      select 字段1,字段2,字段3 from table_name;
      select * from table_name;
      

      *为通配符,表示查询所有字段。

    2. 设置别名

      可以给查询的字段设置别名,其中AS可以省略

      select 字段1 as 别名1,字段2 as 别名2,字段3 as 别名3 from table_name;
      
    3. 去除重复记录

      select后面加上distinct。

      select distinct 字段列表 from 表名;
      
  • 条件查询

    条件查询指的是where后面的条件该怎么写,主要见下图

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HJh85zMz-1668930164917)(/Users/oumingwei/Library/Application Support/typora-user-images/image-20220930104851752.png)]

  • 聚合函数

    主要有五种聚合函数(count、max、min、avg、sum).其功能就如其名

    count可以查询某个字段的数量,但是需要主要的是,不会计算字段为NULL的字段,count(*)表示整张表有多少记录.

    max(字段名)求最大的记录。

  • 分组查询

    select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组后过滤条件];
    

    where与having的区别

    • 执行时机不同:where是分组之前进行过滤,如果不满足则不参与分组;而having是对分组之后的数据进行过滤
    • 判断条件不同:where后面不能加聚合函数,having可以。

    注意:

    • 执行顺序:where>聚合函数>having
    • 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段没有任何意义。
  • 排序查询

    select 字段列表 from 表名 order by 字段1 排序方式1,字段2 排序方式2;
    

    支持多字段排序,按照字段顺序,在前面的,先按前面排序,如果前面的字段都相等,再按照后面的字段排序。其中排序方式分为==升序(asc)排序和降序(desc)==排序,默认为asc,asc可以省略。

  • 分页查询

    select 字段列表 from 表名 limit 起始索引,查询记录数;
    

    注意:

    • 起始索引是从0开始,起始索引=(查询页码 - 1)*每页显示数。
    • 分页查询是数据库的方言,不同数据库有不同的实现,mysql数据库中是limit。
    • 如果查询的是第一页的数据,起始索引可以省略,比如limit 10;
  • 执行顺序
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s01UpmMk-1668930164918)(/Users/oumingwei/Library/Application Support/typora-user-images/image-20220930111225307.png)]

DCL用户管理和权限控制
  • 用户管理

    1. 查询用户

      use mysql;
      select * from user;
      

      mysql用户信息存储与mysql数据库中的user表。

    2. 创建用户

      create user '用户名'@'主机名' identified by '密码';
      
    3. 修改用户密码

      alter user '用户名'@'主机名' identified with mysql_native_password by '新密码';
      
    4. 删除用户

      drop user '用户名'@'主机名';
      
  • 权限管理
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J7QHxmg6-1668930164919)(/Users/oumingwei/Library/Application Support/typora-user-images/image-20221002141501080.png)]

    1. 查询权限

      show grants for '用户名'@'主机名';
      
    2. 授予权限

      grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
      
    3. 撤销权限

      revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
      

    注意:

    • 多个权限之间使用逗号隔开
    • 授权时,数据库名和表名都可以使用*进行通配。
函数介绍
  • 字符串函数
    在这里插入图片描述

    注意,substring中start是从1开始的。

  • 数值函数
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MQZPm19j-1668930164921)(/Users/oumingwei/Library/Application Support/typora-user-images/image-20221002142537439.png)]

  • 日期函数
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接(/Users/oumingwei/Library/Application Support/typora-user-images/image-20221002142633797.png)]

    date_add(now(),INTERVAL 70 month);#当前时间往后推70个月
    

    其中date的格式是’2022-1-1’。

  • 流程函数
    在这里插入图片描述

约束

  • 外键约束

    具有外键的表称为子表,外键关联的表称为父表。

    1. 添加外键

      # 建表时添加
      create table 表名(
      字段名 数据类型,
        ......
        [constraint][外键名称] foreign key(外键字段名) references 主表(主表列名)
      );
      # 其他添加
      alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表(主表列名);
      
    2. 删除外键

      alter table 表名 drop foreign key 外键名称;
      
    3. 删除/更新行为

      在这里插入图片描述
      在这里插入图片描述

多表查询
  1. 多表关系

    项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的联系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在各种联系,基本上分为三种:

    • 一对多(多对一):在多的一方建立外键,指向一的一方,即多的一方为子表,一的一方为父表
    • 多对多:建立第三方中间表,中间表至少包含两个外键,分别指向两方
    • 一对一:在任意一方设置外键,指向另一方的主见,并设置外键为唯一。
  2. 多表查询概述
    在这里插入图片描述

    一般在进行多表查询时,如果不加约束条件会产生这样的笛卡尔积的情况,所以后面一般都会有where条件,一般是两个字段相等。

  3. 内连接
    在这里插入图片描述

  4. 外连接

在这里插入图片描述

  1. 自连接

  1. 联合查询

在这里插入图片描述

其中,如果union后面加上all表示不去重,不加all表示去重

  1. 子查询

在这里插入图片描述

事务
  1. 事务简介

    事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起提交给系统,那么这些操作要么一起成功,要么一起失败。抛出异常时进行回滚,保证数据的正确性和完整性。

  2. 事务操作

    • 开启事务

      begin;
      set @@autocommit = 0;
      start transaction;
      
    • 提交事务

      commit;
      
    • 回滚事务

      当出现异常时执行

      rollback;
      
  3. 事务的四大特性

    • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败;
    • 一致性(Consistency):事务完成时,必须使所有的数据保持一致的状态
    • 隔离性(Isolation):数据库提供的隔离机制,保证事务在不受外部并发操作的影响下独立运行。
    • 持久性(Durability):事务一旦提交或回滚,他对数据库的影响就是永久的。
  4. 并发事务问题

    问题描述
    脏读一个事务读到另一个事务还没有提交的数据
    不可重复度一个事务先后读取统一数据,但读的数据不一样。
    幻读一个数据按照条件查询时,没有对应的数据行,但是在插入数据时也发现该数据存在。
  5. 事务隔离级别

    在这里插入图片描述

    表格中的叉表示在这种隔离级别下没有该问题。

    需要设置系统变量transaction_isolation;

    select @@transaction_isolation;
    set [session|global] transaction isolation level {Read uncommitted|Read committed|Repeatable|serializable};
    

进阶

存储引擎

  • MySQL当前默认的存储引擎为InnoDB,这是一个同事兼顾了数据的完整性和正确性以及执行效率的引擎,此外,还需要了解另外两种引擎,MyISAM和Memory引擎

MyISAM:MyISAM作为MySQL早期的默认存储引擎,其特点在于访问速度快,相比于InnoDB,他不支持事务,不支持外键,支持表锁,但不支持行锁。其在磁盘中存储的文件有:xxx.sdi,用于存储表的结构信息;xxx.MYD,用于存储数据;xxx.MYI,用于存储索引。

Memory:Memory引擎相比于InnoDB来说,其数据库数据均存在于内存之中,最大的特点在于其执行速度很快。

InnoDB:InnoDB引擎支持行级锁,支持事务,支持外键。其文件后最名为.ldb

在这里插入图片描述

在选择存储引擎的时候,应该根据饮用系统的特点选择合适的存储引擎,对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合

  • InnoDB:是MySQL的默认存储引擎,支持事务、外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新、删除操作,那么InnoDB引擎是比较合适的选择。
  • MyISAM:如果应用是以读操作和插入操作为主,只有很少的更新和删除操作。并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。
  • MEMORY:见所有数据保存在内存中,访问速度快,通常用于临时表及缓存。MEMORY的缺陷就是对表的大小有限制,太大的表无法缓存在内存中,而且无法保障数据的安全性。

索引

索引概述

索引是为了加快数据的查询速度,降低数据库的IO成本,通过索引列对数据进行排序,降低数据排序成本,降低CPU的消耗。但是索引本身需要占据存储空间,并且在加快查询速度的同时,会降低更新表的效率,因为每一次更新会影响已经建好的索引。

索引的结构

MySQL的索引是在存储引擎中实现的,也就意味着不同的存储引擎有着不同的索引结构,主要包好以下几种:

索引结构描述
B+Tree最常见的索引类型,大部分引擎都支持B+树索引
Hash索引底层实现结构为Hash表,只能做精确查询,无法做范围查询和排序
R-Tree(空间索引)是MyISAM引擎的特殊索引,主要用于地理空间信息数据类型,使用较少
Full-text(全文索引)快速匹配文档

主要了解B+树索引和Hash索引。

  • B+树索引通过字段构建一颗B+树,其特点在于,所有数据都在叶子结点,叶子结点从大到小排列形成一个双向链表。
  • Hash索引通过Hash函数将索引字段映射到某个地址,当多个字段映射到同一个地址时,会构建一个链表。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

索引分类

在存储引擎中,根据索引的存储形式,又可以分为以下两种:

  • 聚集索引:将数据存储与索引放到了一起,索引结构的叶子结点保存了行数据,该索引必须有而且有一个,一般根据主键自动创建,如果没有主键,则按第一个唯一索引作为聚集索引,如果也没有合适的唯一索引,InnoDB会自动生成一个rowid,根据rowid自动创建。
  • 二级索引:将数据与索引分开存储,索引的叶子结点关联的是对应的主键,该索引可存在多个。
索引语法
  • 创建索引

    create  [unique | fulltext] index ind_name on table_name(colmu,...);
    
  • 查看索引

    show index from table_name;
    
  • 删除索引

    drop index idx_name on table_name;
    
SQL性能分析
  • SQL执行频次

    可通过show [session|global] status来展示当前数据库INSERT、UPDATE、DELETE、SELECT的访问频次。效果如下:

在这里插入图片描述

  • 慢查询日志

    慢查询日志记录了所有执行时间超过指定参数long_query_time的SQL语句,慢查询日志默认关闭,需要在==/etc/my.cnf==文件中进行如下修改:

    slow_query_log = 1
    long_query_time = 2
    

    日志文件的路径为:/var/lib/mysqld/localhost-slow.log。

  • profile详情

    执行一系列的业务SQL操作,然后通过以下指令来查看指令的执行耗时。

    # 查看每一条sql执行耗时的基本情况
    show profiles;
    # 查看指定query_id的sql语句各个阶段的耗时情况
    show profile for query query_id;
    # 查看指定query_id的SQL语句执行的cpu情况
    show profile cpu for query query_id;
    
  • explain执行计划

    使用explain或者desc命令获取MySQL如何执行SELECT语句的信息,包括在select语句中表的连接和连接顺序。

    #直接在查询语句前加explain或者desc
    explain select ...
    

在这里插入图片描述

  • id:select查询的序列号,表示查询中执行select子句或者事操作表的顺序(id相同,执行顺序从上到下;id不同,值越大,越先执行)
  • select_type:表示select的类型,常见的取值有SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询,即外层查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(SELECT/WHERE之后包含了子查询)等
  • type:表示连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、index、all。
  • prossible_key:显示可能应用到这张表的索引,一个或多个。
  • key:实际使用的索引,如果为NULL,则没有使用索引
  • key_len:表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好。
  • rows:MySQL认为必须要执行查询的行数,在InnoDB引擎的表中,是一个估计值,可能并不总是准确的
  • filtered:表示返回结果的行数占需要读取行数的百分比
索引使用
  • 最左前缀法则:如果使用联合索引,要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列,如果跳过某一列,索引将部分失效(后面的字段索引失效)。

  • 范围查询:联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效(尽量使用>=,<=).

  • 在索引上列上进行运算操作,索引会失效

  • 字符串不加引号,会存在隐式类型转换,索引将会失效

  • 模糊查询如果在头部使用模糊查询,索引会失效(尾部不会)

  • or连接的条件,如果两侧有一个没有索引,则索引都不会生效

  • 数据分布影响,MySQL评估,当进行全表查询时效率比使用索引还好时,索引失效。

  • SQL提示:SQL中加入提示语来指定MySQL使用那个索引:

    #use index 建议mysql使用某个索引
    explain select * from tb_user use index(idx_user_pro)where profession = '软件工程';
    #ignore 忽略某个索引
    explain select * from tb_user ignore index(idx_user_pro)where profession = '软件工程';
    #force index 强制MySQL使用某个索引
    explain select * from tb_user force index(idx_user_pro)where profession = '软件工程';
    
  • 覆盖索引:尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),能够防止回表查询。

  • 前缀索引:对于较大的字符串,我们可以考虑截取字符串的前缀作索引,能够降低IO浪费,提高查询时间。

  • 推荐使用联合索引。

索引设计原则
  1. 针对数据量较大(百万级以上),且查询比较频繁的表建立索引(更新插入修改频繁建立索引反而降低效率)。
  2. 针对常作为查询条件where、order by、group by后面的字段建立索引。
  3. 尽量选择区分度高的列作为索引,区分度越高,使用索引的效率越高
  4. 如果是字符串类型的字段,字符串较长,可以针对字段特点建立前缀索引
  5. 尽量使用联合索引,减少单列索引,联合索引可以覆盖索引,节省存储空间,避免回表,提高效率
  6. 要控制索引的数量,索引的数量并不是越多越好,太多的索引会影响增删改的效率
  7. 如果索引列不能存储NULL值,在创建表的时候使用NOT NULL进行约束。当优化器知道每列是否包含NULL的时候,可以更好的确定哪个索引更有效的查询。

SQL优化

在这里插入图片描述

插入数据
  • insert优化 :批量插入、手动事务提交、主键顺序插入都能提高插入效率

  • 大批量数据插入:load语句

    # 客户端连接服务端的时候加上 --local-infile
    mysql --local-infile -uroot -p
    # 设置全局参数local_infile = 1,开启本地加载文件导入数据开关
    set global local_infile = 1;
    # 执行load指令加载文件至数据库
    load data local infile 'filepath' into table 'table_name' fields terminated by ',' lines terminated by '\n';
    
主键优化
  • 数据组织方式

    在InnoDB引擎中,表数据是根据主键顺序组织存放的,这种存储方式的表称为索引组织表,主键乱序插入会产生页分裂

    当删除一行数据时,实际上记录并没有物理删除,只是被标识为已删除并且它的空间变得允许被其他记录声明使用。当页中删除的数据达到默认的阈值时,附近的页会合并

  • 主键设计原则

    • 满足业务需求的情况下,尽量降低主键的长度。
    • 插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键。
    • 尽量不要使用UUID做主键或者是其他自然主键,如身份证号。
    • 业务操作时,避免对主键的修改。
order by优化
  • Using filesort:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫filesort排序
  • Using index:通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。
group by优化

建立联合索引

limit优化
select * from table limit 0,10;

大数据量下分页越往后效率越低

覆盖索引+子查询进行优化

count优化

优化思路:自己计数。

count(*),count(主键),count(字段),count(1);

update优化

InnoDB存在行锁机制,只要数据没有提交,行锁不会解。如果where后面的条件字段没有索引,那么就加的是表锁。

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁。

所以优化思路为,根据索引字段进行更新。

视图/存储过程/触发器

视图
  • 视图是一种虚拟存在的表,不存储具体的数据,而只存储数据的逻辑结构,行和列数据定义来自于定义视图查询中使用的表,并且实在使用视图时动态生成。

  • 通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果,所以我们在创建视图时,主要工作就落在创建这条SQL查询语句上

  • 创建视图

    create or replace view 视图名称(列名列表) as select with cascaded | local check option;
    
  • 查询

    查看创建视图语句:show create view 视图名称;
    查看视图数据:select * from 视图名称;
    
  • 修改

    # 方式一
    create or replace view 视图名称(列名列表) as select 语句 with cascaded | local check option;
    # 方式二
    alter view 视图名称 as select 语句 with cascaded | local check option;
    
  • 删除

    drop view [if exists] 视图名称;
    
  • 视图的检查选项

    当在进行视图数据的增删改时,真实的数据是对创建视图时select后面的表进行增删改,这样会导致数据插入到原来的真实表,但是视图中不一定有的情况发生,为了保证数据的正确性和一致性,视图加上检查选项,可以对数据插入等操作进行约束。

    MySQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。为了确定检查的范围,mysql提供了两个选项:

    1. cascaded(默认)
    2. local
      在这里插入图片描述

    cascaded表示级联,v2基于v1创建,v2加了cascaded,v1元本没加,但也相当于家了,在进行v2的插入删除更新操作时,都会检查v1和v2创建时的条件。

    local也会递归检查基于视图的创建条件,但是如果依赖的视图创建时没有加with check option,则不做检查,家了才检查。cascaded无论加不加都要检查。

  • 视图的更新

    要使视图可更新,视图中的行与基础表中的行必须存在一对一的关系。如果视图包含以下任何一项,则该视图不可更新:

    1. 聚合函数或窗口函数
    2. distinct
    3. group by
    4. having
    5. union 或 union all
  • 作用

    1. 简单:视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
    2. 安全:数据库可以授权,但不能授权到数据库特定行和特定列上。通过视图用户只能查询和修改他们所能见到的数据
    3. 数据独立:视图可以帮助用户屏蔽真实表结构变化带来的影响。
存储过程
  • 介绍

    存储过程时事先经过变异并存储在数据库中的一段sql语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。

    存储过程思想上很简单,就是数据库SQL语言层面的代码封装与重用。(可以理解为C++的函数)

  • 特点

    封装,复用

    可以接受参数,也可以返回数据

    减少网络交互,效率提升

  • 创建

    create procedure 存储过程名称([参数列表])
    begin
    		--SQL语句
    end;
    
  • 调用

    call 名称([参数]);
    
  • 查看

    select * from INFORMATION_SCHEMA.ROUTINES where ROUTINE_SCHEMA='xxx';# 查询指定数据库的存储过程及状态信息
    show create procedure 存储过程名称; # 查询某个存储过程的定义
    
  • 删除

    DROP procedure [if exists] 存储过程名称;
    

在写存储过程中有一个小细节,在编写完一条sql语句时我们需要打分号换行写下一条,但分号时数据库默认的SQL语句结束符。此时需要使用delimiter指定在命令行中以什么字符结束语句。

  • 变量

    系统变量是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全局变量(GLOBAL)、会话变量(SESSION)。

    1. 查看系统变量

      SHOW [SESSION|GLOBAL] VARIABLES; # 查看所有系统变量
      show [SESSION|GLOBAL] VARIABLES like '....'; # 模糊匹配
      select @@[SESSION|GLOBAL]系统变量名;# 查看指定变量的值
      
    2. 设置系统变量

      set [SESSION|GLOBAL] 系统变量名 = 值;
      set @@[SESSION|GLOBAL]系统变量名 = 值;
      

      注意:

      如果没有指定SESSION/GLOBAL,默认是session,会话变量

      mysql服务重新启动之后,所设置的全局参数会失效,要想不失效,可在/etc/my.cnf中配置。

    用户定义变量是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用“@变量名”使用就可以。其作用域为当前连接

    1. 赋值

      set @var_name = expr;
      set  @var_name := expr;
      select  @var_name := expr;
      select 字段名 into  @var_name from 表名;
      
    2. 使用

      select @var_name;
      

    局部变量是根据需要定义的在局部生效的变量,访问之前需要declare声明。可用作存储过程内的局部变量和输入参数,局部变量的范围是其内声明的begin…end块。

    1. 声明

      declare 变量名 变量类型 [default ...];
      

      变量类型就是数据库字段类型:int,bigint,char,varchar,date,time等。

    2. 赋值

      set 变量名 = 值;
      set 变量名 := 值;
      select 字段名 into 变量名 from 表名;
      
  • if

    语法

    if 条件1 then
    elseif 条件2 then
    else
    end if;
    
  • 参数

    类型含义备注
    IN输入参数默认
    out输出
    inout既可以输入也可输出

    用法:

    create procedure 存储过程名称([IN/out/INOUT 参数名称 参数类型])
    begin
    		-- SQL语句
    end;
    
  • case

    1. 语法一

      CASE case_value
      				WHEN when_value1 then statement_list1
      				[WHEN when_value2 then statement_list2]...
      				[ELSE statement_list]
      end case;
      
    2. 语法二

      CASE case_value
      				WHEN search_condition1 then statement_list1
      				[WHEN search_condition2 then statement_list2]...
      				[ELSE statement_list]
      end case;
      
  • while

    while循环是有条件的循环控制语句。满足条件后,再执行循环体中的SQL语句。具体语法为:

    WHILE 条件 DO
    				SQL逻辑
    end while;
    
  • repeat

    repeat是有条件的循环控制语句,当满足条件时退出循环。具体语法为:

    repeat
    			SQL逻辑
    			until 条件
    end repeat;
    
  • loop

    loop实现简单的循环,如果不在SQL逻辑中增加退出循环的条件,可以用其来实现简单的死循环,loop可以配合以下两个语句使用

    1. leave:退出循环,相当于C++中的break;
    2. iterate:相当于C++中的continue;
    [begin_label:] loop
    				sql逻辑
    end loop[end_label];
    

    Leave label; 退出指定标记的循环体

    Iterate label;直接进入下一次循环

  • 游标

    游标(cursor)是用来存储查询结果集的数据类型,在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明、open、fetch和close,其语法分别如下。

    1. 声明游标

      declare 游标名称 cursor for 查询语句;
      
    2. 打开游标

      open 游标名称;
      
    3. 获取游标记录

      FETCH 游标名称 into 变量 [,变量];
      
    4. 关闭游标

      close 游标名称;
      
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值