• 20190823 尚硅谷MySQL核心技术


    背景

    • 视频时间:2017.09
    • MySQL版本:5.5

    MySQL基础

    命令行启动、停止MySQL:

    net start MySQL(这里是注册的服务名称)
    net stop MySQL
    

    命令行连接MySQL:

    mysql -h localhost -P 3306 -u root -p xxx
    -h 主机,可省略
    -P 端口号,可省略
    -u 用户名
    -p 密码,与密码之间不能有空格,其他可有可无
    

    常用命令

    1. 查看当前所有的数据库
    show databases;
    
    1. 打开指定的库
    use 库名
    
    1. 查看当前库的所有表
    show tables;
    
    1. 查看其它库的所有表
    show tables from 库名;
    
    1. 查看当前所在数据库
    select DATABASE();
    
    1. 查看表结构
    desc 表名;
    
    1. 查看服务器的版本
      方式一:登录到mysql服务端
    select version();
    

    方式二:没有登录到mysql服务端

    mysql --version
    

    mysql --V
    

    MySQL的语法规范

    1. 不区分大小写,但建议关键字大写,表名、列名小写
    2. 每条命令最好用分号结尾
    3. 每条命令根据需要,可以进行缩进 或换行
    4. 注释
      • 单行注释:# 注释文字
      • 单行注释:-- 注释文字
      • 多行注释:/* 注释文字 */

    SQL的语言分类

    • DQL(Data Query Language):数据查询语言
      select
    • DML(Data Manipulate Language):数据操作语言
      insert 、update、delete
    • DDL(Data Define Languge):数据定义语言
      create、drop、alter
    • TCL(Transaction Control Language):事务控制语言
      commit、rollback

    查询常量值

    SELECT 100;
    SELECT 'john';
    

    查询表达式

    SELECT 100%98;
    

    查询函数

    SELECT VERSION();
    

    别名特殊时,加上双引号:

    SELECT salary AS "out put" FROM employees;
    

    mysql中的 + 号:

    仅仅只有一个功能:运算符

    -- 两个操作数都为数值型,则做加法运算
    select 100+90; 
    
    -- 只要其中一方为字符型,试图将字符型数值转换成数值型
    -- 如果转换成功,则继续做加法运算
    select '123'+90;
    
    -- 如果转换失败,则将字符型数值转换成0
    select 'john'+90;	
    
    -- 只要其中一方为null,则结果肯定为null
    select null+10; 
    
    -- 会试图转换字符串的开始部分为数字
    SELECT '123abc'+'3a2a'; 
    

    字符串连接函数:

    SELECT CONCAT('a','b','c') AS 结果;
    

    null与其他字符串左连接时结果为null;

    IFNULL函数判断是否为空:

    SELECT 
    	IFNULL(commission_pct,0) AS 奖金率,
    	commission_pct
    FROM 
    	employees;
    

    条件查询:

    一、按条件表达式筛选

    简单条件运算符:> < = != <> >= <=
    

    二、按逻辑表达式筛选

    逻辑运算符:
    作用:用于连接条件表达式
    	&& || !
    	and or not
    	
    &&和and:两个条件都为true,结果为true,反之为false  
    ||或or: 只要有一个条件为true,结果为true,反之为false  
    !或not: 如果连接的条件本身为false,结果为true,反之为false  
    

    三、模糊查询

    	like
    	between and
    	in
    	is null
    

    like:
    ①一般和通配符搭配使用
    通配符:
    % 任意多个字符,包含0个字符
    _ 任意单个字符

    可以直接使用转义符,也可以指定转义符:

    last_name LIKE '_\_%';  
    last_name LIKE '_$_%' ESCAPE '$';
    

    安全等于 <=>
    既可以判断NULL值,又可以判断普通的数值

    ISNULL

    判断是否为空
    1 为是 0为否

    order by 支持别名排序

    DATEDIFF相隔天数:

    SELECT DATEDIFF('1995-2-7','1995-2-6');
    

    单行函数

    #一、字符函数

    • length:获取参数值的字节个数

    • concat:拼接字符串

    • upperlower:转大写、小写

    • substrsubstring:截取字符串

      注意:索引从 1 开始

      截取从指定索引处后面所有字符

    • instr 返回子串第一次出现的索引,如果找不到返回0

    • trim

    • lpad 用指定的字符实现左填充指定长度

    • rpad 用指定的字符实现右填充指定长度

    • replace 替换

    #二、数学函数

    • round 四舍五入
    • ceil 向上取整,返回 >= 该参数的最小整数
    • floor 向下取整,返回 <= 该参数的最大整数
    • truncate 截断
    • mod取余

    #三、日期函数

    now 返回当前系统日期+时间

    SELECT NOW();
    

    curdate 返回当前系统日期,不包含时间

    SELECT CURDATE();
    

    curtime 返回当前时间,不包含日期

    SELECT CURTIME();
    

    可以获取指定的部分,年、月、日、小时、分钟、秒

    SELECT YEAR(NOW()) 年;
    SELECT YEAR('1998-1-1') 年;
    
    SELECT  YEAR(hiredate) 年 FROM employees;
    
    SELECT MONTH(NOW()) 月;
    SELECT MONTHNAME(NOW()) 月;
    

    str_to_date 将字符通过指定的格式转换成日期

    SELECT STR_TO_DATE('1998-3-2','%Y-%c-%d') AS out_put;
    

    date_format 将日期转换成字符

    SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') AS out_put;
    
    序号 格式符 功能
    1 %Y 4 位的年份
    2 %y 2 位的年份
    3 %m 月份( 01,02…11,12)
    4 %c 月份( 1,2,…11,12)
    5 %d 日( 01,02,…)
    6 %H 小时( 24 小时制)
    7 %h 小时( 12 小时制)
    8 %i 分钟( 00,01…59)
    9 %s 秒( 00,01,…59)

    #四、其他函数

    SELECT VERSION();
    SELECT DATABASE();
    SELECT USER();
    

    #五、流程控制函数

    #1.if函数: if else 的效果

    SELECT IF(10<5,'大','小');
    

    #2.case 函数的使用一: switch case 的效果

    #3.case 函数的使用二:类似于 多重if

    分组函数

    sum 求和、avg 平均值、max 最大值 、min 最小值 、count 计算个数

    特点:

    1. sum、avg一般用于处理数值型
      max、min、count可以处理任何类型
    2. 以上分组函数都忽略null值
    3. 可以和distinct搭配实现去重的运算
    4. count函数的单独介绍
      一般使用count(*)用作统计行数
    SELECT COUNT(salary) FROM employees;
    SELECT COUNT(*) FROM employees;
    SELECT COUNT(1) FROM employees;
    

    效率:

    MYISAM 存储引擎下 ,COUNT(*)的效率高

    INNODB 存储引擎下,COUNT(*)COUNT(1)的效率差不多,比COUNT(字段)要高一些

    1. 和分组函数一同查询的字段要求是group by后的字段

    筛选分类

    筛选分为两类:分组前筛选和分组后筛选

    分类 针对的表 位置 连接的关键字
    分组前筛选 原始表 group by前 where
    分组后筛选 group by后的结果集 group by后 having

    一般来讲,能用分组前筛选的,尽量使用分组前筛选,提高效率

    MySQL中group by 子句和having子句后都支持别名,与Oracle不同。

    where子句后都不支持别名。

    连接查询:

    如果为表起了别名,则查询的字段就不能使用原来的表名去限定。

    sql99语法的连接查询

    内连接:

    inner join == join

    MySQL不支持全外连接 full join

    交叉连接就是笛卡尔乘积。cross join

    子查询

    分类:
    按子查询出现的位置:

    select后面:
    	仅仅支持标量子查询
    from后面:
    	支持表子查询
    where或having后面:★
    	标量子查询(单行) √
    	列子查询  (多行) √
    	行子查询
    exists后面(相关子查询)
    	表子查询
    

    按结果集的行列数不同:

    标量子查询(结果集只有一行一列)
    列子查询(结果集只有一列多行)
    行子查询(结果集有一行多列)
    表子查询(结果集一般为多行多列)
    

    标量子查询,一般搭配着单行操作符使用

    > < >= <= = <>
    

    列子查询,一般搭配着多行操作符使用

    in、any/some、all
    

    语法:

    exists(完整的查询语句)
    

    结果:1或0

    exists子句先执行主查询,在执行子查询。

    分页查询

    语法: 执行顺序:
    select 查询列表	 |						7
    from 表				 |					1
    【join type join 表2	 |						2
    on 连接条件					 |			3
    where 筛选条件				 |			4
    group by 分组字段			 |				5
    having 分组后的筛选			 |			6
    order by 排序的字段】		 |				8
    limit 【offset,】size;		 |				9
    
    
    offset 要显示条目的起始索引(起始索引从0开始),不写默认为0  
    size 要显示的条目个数
    

    特点:

    limit语句放在查询语句的最后
    公式:要显示的页数 page,每页的条目数 size
    
    select 查询列表
    	from 表
    	limit (page-1)*size,size;
    	
    	size=10
    	page  
    	1	0
    	2  	10
    	3	20
    

    DDL 数据操纵语言

    MySQL的另一种插入语法:

    insert into 表名
    set 列名=值,列名=值,...
    
    INSERT INTO beauty
    SET id=19,NAME='刘涛',phone='999';
    

    多行插入:

    INSERT INTO beauty
    VALUES(23,'唐艺昕1','女','1990-4-23','1898888888',NULL,2)
    ,(24,'唐艺昕2','女','1990-4-23','1898888888',NULL,2)
    ,(25,'唐艺昕3','女','1990-4-23','1898888888',NULL,2);
    
    INSERT INTO beauty(id,NAME,phone)
    SELECT id,boyname,'1234567'
    FROM boys WHERE id<3;
    

    1. 修改单表的记录★

    语法:

    update 表名
    set 列=新值,列=新值,...
    where 筛选条件;
    

    2. 修改多表的记录【补充】

    语法:
    sql92语法:

    update 表1 别名,表2 别名
    set 列=值,...
    where 连接条件
    and 筛选条件;
    

    sql99语法:

    update 表1 别名
    inner|left|right join 表2 别名
    on 连接条件
    set 列=值,...
    where 筛选条件;
    

    删除表记录

    方式一:delete
    语法:

    1、单表的删除【★】

    delete from 表名 where 筛选条件
    

    2、多表的删除【补充】

    sql92语法:

    delete 表1的别名,表2的别名
    from 表1 别名,表2 别名
    where 连接条件
    and 筛选条件;
    

    sql99语法:

    delete 表1的别名,表2的别名
    from 表1 别名
    inner|left|right join 表2 别名 on 连接条件
    where 筛选条件;
    

    方式二:truncate
    语法:

    truncate table 表名;
    

    #delete VS truncate【面试题★】

    1. delete 可以加where 条件,truncate不能加

    2. truncate删除,效率高一丢丢

    3. 假如要删除的表中有自增长列,

    如果用delete删除后,再插入数据,自增长列的值从断点开始,

    而truncate删除后,再插入数据,自增长列的值从1开始。

    1. truncate删除没有返回值,delete删除有返回值

    2. truncate删除不能回滚,delete删除可以回滚.

    DDL语言 数据定义语言

    一、库的管理
    创建、修改、删除
    二、表的管理
    创建、修改、删除

    创建: create
    修改: alter
    删除: drop

    #一、库的管理

    #1、库的创建

    语法:

    create database  [if not exists] 库名;
    

    案例:创建库Books

    CREATE DATABASE IF NOT EXISTS books ;
    

    #2、库的修改

    RENAME DATABASE books TO 新库名;
    

    更改库的字符集

    ALTER DATABASE books CHARACTER SET gbk;
    

    #3、库的删除

    DROP DATABASE IF EXISTS books;
    

    #二、表的管理

    #1.表的创建 ★

    语法:

    create table 表名(
    	列名 列的类型【(长度) 约束】,
    	列名 列的类型【(长度) 约束】,
    	列名 列的类型【(长度) 约束】,
    	...
    	列名 列的类型【(长度) 约束】
    )
    

    案例:创建表Book

    CREATE TABLE book(
    	id INT,#编号
    	bName VARCHAR(20),#图书名
    	price DOUBLE,#价格
    	authorId  INT,#作者编号
    	publishDate DATETIME#出版日期
    );
    
    DESC book;
    

    案例:创建表author

    CREATE TABLE IF NOT EXISTS author(
    	id INT,
    	au_name VARCHAR(20),
    	nation VARCHAR(10)
    
    )
    DESC author;
    

    #2.表的修改

    语法

    alter table 表名 add|drop|modify|change column 列名 【列类型 约束】;
    
    1. 修改列名
    ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;
    
    1. 修改列的类型或约束
    ALTER TABLE book MODIFY COLUMN pubdate TIMESTAMP;
    
    1. 添加新列
    ALTER TABLE author ADD COLUMN annual DOUBLE;
    
    1. 删除列
    ALTER TABLE book_author DROP COLUMN  annual;
    
    1. 修改表名
    ALTER TABLE author RENAME TO book_author;
    
    DESC book;
    

    #3.表的删除

    DROP TABLE IF EXISTS book_author;
    

    通用的写法:

    DROP DATABASE IF EXISTS 旧库名;
    CREATE DATABASE 新库名;
    
    
    DROP TABLE IF EXISTS 旧表名;
    CREATE TABLE  表名();
    

    #4.表的复制

    1.仅仅复制表的结构

    CREATE TABLE copy LIKE author;
    

    2.复制表的结构+数据

    CREATE TABLE copy2 
    SELECT * FROM author;
    

    数据类型

    常见的数据类型

    数值型:
    
    	整型:
    	小数:
    		定点数
    		浮点数
    字符型:
    
    	较短的文本:char、varchar
    	较长的文本:text、blob(较长的二进制数据)
    
    日期型:
    

    #一、整型

    分类:

    类型
    占用字节 1 2 3 4 8
    类型 占用字节
    tinyint 1
    smallint 2
    mediumint 3
    int/integer 4
    bigint 8

    特点:

    1. 如果不设置无符号还是有符号,默认是有符号,如果想设置无符号,需要添加 unsigned 关键字

    2. 如果插入的数值超出了整型的范围,会报out of range异常,并且插入临界值

    3. 如果不设置长度,会有默认的长度

      长度代表了显示的最大宽度,如果不够会用 0 在左边填充,但必须搭配 zerofill 使用!

    #二、小数

    分类:

    1. 浮点型
    • float(M,D)
    • double(M,D)
    1. 定点型
    • dec(M,D)
    • decimal(M,D)

    特点:

    1. M:整数部位+小数部位
      D:小数部位
      如果超过范围,则插入临界值

    2. M和D都可以省略
      如果是decimal,则M默认为10,D默认为0
      如果是float和double,则会根据插入的数值的精度来决定精度

    3. 定点型的精确度较高,如果要求插入数值的精度较高如货币运算等则考虑使用

    原则:

    所选择的类型越简单越好,能保存数值的类型越小越好

    #三、字符型

    较短的文本:

    • char
    • varchar

    其他:

    • binary 和 varbinary 用于保存较短的二进制
    • enum 用于保存枚举
    • set 用于保存集合

    较长的文本:

    • text
    • blob(较大的二进制)

    特点:

    写法 M的意思 特点 空间的耗费 效率
    char char(M) 最大的字符数,可以省略,默认为1 固定长度的字符 比较耗费
    varchar varchar(M) 最大的字符数,不可以省略 可变长度的字符 比较节省

    枚举类型:

    CREATE TABLE tab_char(
    	c1 ENUM('a','b','c')
    );
    INSERT INTO tab_char VALUES('a');
    INSERT INTO tab_char VALUES('b');
    INSERT INTO tab_char VALUES('c');
    

    set类型:

    CREATE TABLE tab_set(
    	s1 SET('a','b','c','d')
    );
    INSERT INTO tab_set VALUES('a');
    INSERT INTO tab_set VALUES('A,B');
    INSERT INTO tab_set VALUES('a,c,d');
    

    #四、日期型

    分类:

    • date 只保存日期

    • time 只保存时间

    • year 只保存年

    • datetime 保存日期+时间

    • timestamp 保存日期+时间

    特点:

    类型 字节 范围 时区等的影响
    datetime 8 1000-9999 不受
    timestamp 4 1970-2038

    常见约束

    含义:一种限制,用于限制表中的数据,为了保证表中的数据的准确和可靠性

    分类:六大约束

    • NOT NULL

      非空,用于保证该字段的值不能为空

    • DEFAULT

      默认值,用于保证该字段有默认值

    • PRIMARY KEY

      主键,用于保证该字段的值具有唯一性,并且非空

    • UNIQUE

      唯一,用于保证该字段的值具有唯一性,可以为空

    • CHECK

      检查约束【mysql中不支持】

      MySQL 只是可以使用 check 约束,但不会强制的遵循check约束!

    • FOREIGN KEY

      外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值

      在从表添加外键约束,用于引用主表中某列的值

    添加约束的时机:

    1. 创建表时
    2. 修改表时

    约束的添加分类:

    • 列级约束:

      六大约束语法上都支持,但外键约束没有效果

    • 表级约束:

      除了非空、默认,其他的都支持

    #1.添加列级约束

    语法:

    直接在字段名和类型后面追加 约束类型即可。

    只支持:默认、非空、主键、唯一

    CREATE TABLE stuinfo(
    	id INT PRIMARY KEY,#主键
    	stuName VARCHAR(20) NOT NULL UNIQUE,#非空
    	gender CHAR(1) CHECK(gender='男' OR gender ='女'),#检查
    	seat INT UNIQUE,#唯一
    	age INT DEFAULT  18,#默认约束
    	majorId INT REFERENCES major(id)#外键
    );
    

    #2.添加表级约束

    语法:在各个字段的最下面
    【constraint 约束名】 约束类型(字段名)

    DROP TABLE IF EXISTS stuinfo;
    CREATE TABLE stuinfo(
    	id INT,
    	stuname VARCHAR(20),
    	gender CHAR(1),
    	seat INT,
    	age INT,
    	majorid INT,
    	
    	CONSTRAINT pk PRIMARY KEY(id),#主键
    	CONSTRAINT uq UNIQUE(seat),#唯一键
    	CONSTRAINT ck CHECK(gender ='男' OR gender  = '女'),#检查
    	CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外键
    	
    );
    

    通用的写法:★

    CREATE TABLE IF NOT EXISTS stuinfo(
    	id INT PRIMARY KEY,
    	stuname VARCHAR(20),
    	sex CHAR(1),
    	age INT DEFAULT 18,
    	seat INT UNIQUE,
    	majorid INT,
    	CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)
    );
    

    主键和唯一的大对比:

    类型 保证唯一性 是否允许为空 一个表中可以有多少个 是否允许组合
    主键 × 至多有1个 √,但不推荐
    唯一 可以有多个 √,但不推荐

    外键:

    1、要求在从表设置外键关系
    2、从表的外键列的类型和主表的关联列的类型要求一致或兼容,名称无要求
    3、主表的关联列必须是一个key(一般是主键或唯一)
    4、插入数据时,先插入主表,再插入从表
    	删除数据时,先删除从表,再删除主表
    

    #二、修改表时添加约束

    1、添加列级约束

    alter table 表名 modify column 字段名 字段类型 新约束;
    

    2、添加表级约束

    alter table 表名 add 【constraint 约束名】 约束类型(字段名) 【外键的引用】;
    
    DROP TABLE IF EXISTS stuinfo;
    CREATE TABLE stuinfo(
    	id INT,
    	stuname VARCHAR(20),
    	gender CHAR(1),
    	seat INT,
    	age INT,
    	majorid INT
    )
    DESC stuinfo;
    
    1. 添加非空约束
    ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20)  NOT NULL;
    
    1. 添加默认约束
    ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;
    
    1. 添加主键

      ① 列级约束

    ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;
    

    ​ ② 表级约束

    ALTER TABLE stuinfo ADD PRIMARY KEY(id);
    
    1. 添加唯一

      ① 列级约束

    ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
    

    ​ ② 表级约束

    ALTER TABLE stuinfo ADD UNIQUE(seat);
    
    1. 添加外键
    ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id);
    

    #三、修改表时删除约束

    1. 删除非空约束
    ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;
    
    1. 删除默认约束
    ALTER TABLE stuinfo MODIFY COLUMN age INT ;
    
    1. 删除主键
    ALTER TABLE stuinfo DROP PRIMARY KEY;
    
    1. 删除唯一
    ALTER TABLE stuinfo DROP INDEX seat;
    
    1. 删除外键
    ALTER TABLE stuinfo DROP FOREIGN KEY fk_stuinfo_major;
    

    标识列

    又称为自增长列

    含义:可以不用手动的插入值,系统提供默认的序列值

    特点:

    1. 标识列必须和主键搭配吗?不一定,但要求是一个key
    2. 一个表可以有几个标识列?至多一个!
    3. 标识列的类型只能是数值型
    4. 标识列可以通过 SET auto_increment_increment=3; 设置步长,可以通过 手动插入值,设置起始值

    #一、创建表时设置标识列

    DROP TABLE IF EXISTS tab_identity;
    CREATE TABLE tab_identity(
    	id INT  ,
    	NAME FLOAT UNIQUE AUTO_INCREMENT,
    	seat INT 
    );
    TRUNCATE TABLE tab_identity;
    
    
    INSERT INTO tab_identity(id,NAME) VALUES(NULL,'john');
    INSERT INTO tab_identity(NAME) VALUES('lucy');
    SELECT * FROM tab_identity;
    
    
    SHOW VARIABLES LIKE '%auto_increment%';
    
    
    SET auto_increment_increment=3;
    

    TCL 事务控制语言

    事务的特性:

    ACID

    • 原子性:一个事务不可再分割,要么都执行要么都不执行
    • 一致性:一个事务执行会使数据从一个一致状态切换到另外一个一致状态
    • 隔离性:一个事务的执行不受其他事务的干扰
    • 持久性:一个事务一旦提交,则会永久的改变数据库的数据.

    事务的创建

    隐式事务:事务没有明显的开启和结束的标记
    比如insert、update、delete语句

    delete from 表 where id =1;
    

    显式事务:事务具有明显的开启和结束的标记
    前提:必须先设置自动提交功能为禁用

    set autocommit=0;
    

    步骤1:开启事务

    set autocommit=0;
    start transaction; 	# 可选的
    

    步骤2:编写事务中的sql语句(select insert update delete)

    语句1;
    语句2;
    ...
    

    步骤3:结束事务

    commit;		# 提交事务
    rollback;	# 回滚事务
    
    savepoint 节点名;		# 设置保存点
    

    并发问题

    • 脏读

      对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段之后, 若 T2 回滚, T1读取的内容就是临时且无效的

    • 不可重复读

      对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段之后, T1再次读取同一个字段, 值就不同了.

    • 幻读

      对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行.

    事务的隔离级别:

    类型 脏读 不可重复读 幻读
    read uncommitted
    read committed ×
    repeatable read × ×
    serializable × × ×

    mysql中默认第三个隔离级别 repeatable read

    oracle中默认第二个隔离级别 read committed

    查看隔离级别:

    select @@tx_isolation;
    

    MySQL 8中是:

    SELECT @@TRANSACTION_ISOLATION;
    

    设置隔离级别

    set session|global transaction isolation level 隔离级别;
    

    视图

    mysql5.1版本出现的新特性

    #一、创建视图

    语法:

    create view 视图名
    as
    查询语句;
    

    #二、视图的修改

    方式一:

    create or replace view  视图名
    as
    查询语句;
    

    方式二:

    语法:

    alter view 视图名
    as 
    查询语句;
    

    #三、删除视图

    语法:

    drop view 视图名,视图名,...;
    
    DROP VIEW emp_v1,emp_v2,myv3;
    

    #四、查看视图

    DESC myv3;
    
    SHOW CREATE VIEW myv3;
    

    #五、视图的更新

    具备以下特点的视图不允许更新

    #① 包含以下关键字的sql语句:分组函数、distinct、group  by、having、union或者union all
    #② 常量视图
    #③ select中包含子查询
    #④ join
    #⑤ from一个不能更新的视图
    #⑥ where子句的子查询引用了from子句中的表
    

    变量

    系统变量:

    全局变量  
    会话变量
    

    自定义变量:

    用户变量  
    局部变量
    

    #一、系统变量

    说明:变量由系统定义,不是用户定义,属于服务器层面
    注意:全局变量需要添加global关键字,会话变量需要添加session关键字,如果不写,默认会话级别

    使用步骤:

    1. 查看所有系统变量
    show global|【session】variables;
    
    1. 查看满足条件的部分系统变量
    show global|【session】 variables like '%char%';
    
    1. 查看指定的系统变量的值
    select @@global|【session】系统变量名;
    
    1. 为某个系统变量赋值
      方式一:
    set global|【session】系统变量名=值;
    

    方式二:

    set @@global|【session】系统变量名=值;
    

    #1》全局变量

    作用域:针对于所有会话(连接)有效,但不能跨重启

    ①查看所有全局变量

    SHOW GLOBAL VARIABLES;
    

    ②查看满足条件的部分系统变量

    SHOW GLOBAL VARIABLES LIKE '%char%';
    

    ③查看指定的系统变量的值

    SELECT @@global.autocommit;
    

    ④为某个系统变量赋值

    SET @@global.autocommit=0;
    SET GLOBAL autocommit=0;
    

    #2》会话变量

    作用域:针对于当前会话(连接)有效

    ①查看所有会话变量

    SHOW SESSION VARIABLES;
    

    ②查看满足条件的部分会话变量

    SHOW SESSION VARIABLES LIKE '%char%';
    

    ③查看指定的会话变量的值

    SELECT @@autocommit;
    SELECT @@session.tx_isolation;
    

    ④为某个会话变量赋值

    SET @@session.tx_isolation='read-uncommitted';
    SET SESSION tx_isolation='read-committed';
    

    #二、自定义变量

    说明:变量由用户自定义,而不是系统提供的

    使用步骤:

    1. 声明
    2. 赋值
    3. 使用(查看、比较、运算等)

    #1》用户变量

    作用域:针对于当前会话(连接)有效,作用域同于会话变量

    赋值操作符:=或:=

    ①声明并初始化

    SET @变量名=值;
    SET @变量名:=值;
    SELECT @变量名:=值;
    

    ②赋值(更新变量的值)

    方式一:

    SET @变量名=值;
    SET @变量名:=值;
    SELECT @变量名:=值;
    

    方式二:

    SELECT 字段 INTO @变量名
    FROM 表;
    

    ③使用(查看变量的值)

    SELECT @变量名;
    

    #2》局部变量

    作用域:仅仅在定义它的begin end块中有效

    应用在 begin end中的第一句话

    ①声明

    DECLARE 变量名 类型;
    DECLARE 变量名 类型 【DEFAULT 值】;
    

    ②赋值(更新变量的值)

    方式一:

    SET 局部变量名=值;
    SET 局部变量名:=值;
    SELECT 局部变量名:=值;
    

    方式二:

    SELECT 字段 INTO 具备变量名
    	FROM 表;
    

    ③使用(查看变量的值)

    SELECT 局部变量名;
    

    案例:声明两个变量,求和并打印

    用户变量

    SET @m=1;
    SET @n=1;
    SET @sum=@m+@n;
    SELECT @sum;
    
    类型 作用域 定义位置 语法
    用户变量 当前会话 会话的任何地方 加@符号,不用指定类型
    局部变量 定义它的BEGIN END中 BEGIN END的第一句话 一般不用加@,需要指定类型

    存储过程

    含义:一组预先编译好的SQL语句的集合,理解成批处理语句

    1、提高代码的重用性
    2、简化操作
    3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
    

    #一、创建语法

    CREATE PROCEDURE 存储过程名(参数列表)
    BEGIN
    	存储过程体(一组合法的SQL语句)
    END
    

    注意:
    1、参数列表包含三部分

    参数模式 参数名 参数类型

    举例:

    in stuname varchar(20)

    参数模式:

    in:该参数可以作为输入,也就是该参数需要调用方传入值
    out:该参数可以作为输出,也就是该参数可以作为返回值
    inout:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又可以返回值
    

    2、如果存储过程体仅仅只有一句话,begin end可以省略

    存储过程体中的每条sql语句的结尾要求必须加分号。

    存储过程的结尾可以使用 delimiter 重新设置

    语法:

    delimiter 结束标记
    

    案例:

    delimiter $
    

    #二、调用语法

    CALL 存储过程名(实参列表);
    

    #1.空参列表

    案例:插入到admin表中五条记录

    DELIMITER $
    CREATE PROCEDURE myp1()
    BEGIN
    	INSERT INTO admin(username,`password`) 
    	VALUES('john1','0000'),('lily','0000'),('rose','0000'),('jack','0000'),('tom','0000');
    END $
    

    调用

    CALL myp1()$
    

    #2.创建带 in 模式参数的存储过程

    案例2 :创建存储过程实现,用户是否登录成功

    CREATE PROCEDURE myp4(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
    BEGIN
    	DECLARE result INT DEFAULT 0;#声明并初始化
    	
    	SELECT COUNT(*) INTO result#赋值
    	FROM admin
    	WHERE admin.username = username
    	AND admin.password = PASSWORD;
    	
    	SELECT IF(result>0,'成功','失败');#使用
    END $
    

    调用

    CALL myp4('张飞','8888')$
    

    #3.创建 out 模式参数的存储过程

    案例2:根据输入的女神名,返回对应的男神名和魅力值

    CREATE PROCEDURE myp7(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT usercp INT) 
    BEGIN
    	SELECT boys.boyname ,boys.usercp INTO boyname,usercp
    	FROM boys 
    	RIGHT JOIN
    	beauty b ON b.boyfriend_id = boys.id
    	WHERE b.name=beautyName ;
    	
    END $
    

    调用

    CALL myp7('小昭',@name,@cp)$
    SELECT @name,@cp$
    

    #4.创建带 inout 模式参数的存储过程

    案例1:传入a和b两个值,最终a和b都翻倍并返回

    CREATE PROCEDURE myp8(INOUT a INT ,INOUT b INT)
    BEGIN
    	SET a=a*2;
    	SET b=b*2;
    END $
    

    调用

    SET @m=10$
    SET @n=20$
    CALL myp8(@m,@n)$
    SELECT @m,@n$
    

    #三、删除存储过程

    语法:drop procedure 存储过程名

    DROP PROCEDURE p1;
    DROP PROCEDURE p2,p3;#×
    

    #四、查看存储过程的信息

    SHOW CREATE PROCEDURE myp2;
    

    函数

    含义:一组预先编译好的SQL语句的集合,理解成批处理语句

    1、提高代码的重用性
    2、简化操作
    3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
    

    区别:

    • 存储过程:可以有0个返回,也可以有多个返回,适合做批量插入、批量更新
    • 函数:有且仅有1 个返回,适合做处理数据后返回一个结果

    #一、创建语法

    CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
    BEGIN
    	函数体
    END
    

    注意:

    1. 参数列表 包含两部分:
      参数名 参数类型

    2. 函数体:肯定会有return语句,如果没有会报错

    如果return语句没有放在函数体的最后也不报错,但不建议

    return 值;

    1. 函数体中仅有一句话,则可以省略 begin end

    2. 使用 delimiter 语句设置结束标记

    #二、调用语法

    SELECT 函数名(参数列表)
    

    案例2:根据部门名,返回该部门的平均工资

    CREATE FUNCTION myf3(deptName VARCHAR(20)) RETURNS DOUBLE
    BEGIN
    	DECLARE sal DOUBLE ;
    	SELECT AVG(salary) INTO sal
    	FROM employees e
    	JOIN departments d ON e.department_id = d.department_id
    	WHERE d.department_name=deptName;
    	RETURN sal;
    END $
    
    SELECT myf3('IT')$
    

    #三、查看函数

    SHOW CREATE FUNCTION myf3;
    

    #四、删除函数

    DROP FUNCTION myf3;
    

    流程控制结构

    顺序、分支、循环

    #一、分支结构

    #1.if函数

    语法:if(条件,值1,值2)
    功能:实现双分支
    应用在begin end中或外面
    

    #2.case结构

    语法:

    情况1:类似于switch

    case 变量或表达式
    when 值1 then 语句1;
    when 值2 then 语句2;
    ...
    else 语句n;
    end
    

    情况2:

    case 
    when 条件1 then 语句1;
    when 条件2 then 语句2;
    ...
    else 语句n;
    end case
    

    应用在 begin end 中或外面

    #3.if结构

    语法:

    if 条件1 then 语句1;
    elseif 条件2 then 语句2;
    ....
    else 语句n;
    end if;
    

    功能:类似于多重if

    只能应用在begin end 中

    #二、循环结构

    分类:
    while、loop、repeat

    循环控制:

    iterate类似于 continue,继续,结束本次循环,继续下一次
    leave 类似于  break,跳出,结束当前所在的循环
    

    #1.while

    语法:

    【标签:】while 循环条件 do
    	循环体;
    end while【 标签】;
    

    联想:

    while(循环条件){
    	循环体;
    }
    

    #2.loop

    语法:

    【标签:】loop
    	循环体;
    end loop 【标签】;
    

    可以用来模拟简单的死循环

    #3.repeat

    语法:

    【标签:】repeat
    	循环体;
    until 结束循环的条件
    end repeat 【标签】;
    

    #2.添加 leave 语句

    案例:批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止

    TRUNCATE TABLE admin$
    DROP PROCEDURE test_while1$
    CREATE PROCEDURE test_while1(IN insertCount INT)
    BEGIN
    	DECLARE i INT DEFAULT 1;
    	a:WHILE i<=insertCount DO
    		INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
    		IF i>=20 THEN LEAVE a;
    		END IF;
    		SET i=i+1;
    	END WHILE a;
    END $
    
    
    CALL test_while1(100)$
    
  • 相关阅读:
    相亲数问题
    MySQL导入导出命令
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/huangwenjie/p/11401846.html
Copyright © 2020-2023  润新知