MySQL好好学一(MySQL基础语法和SQL查询)

MySQL好好学一(MySQL基础语法和SQL查询)

大纲

  1. SQL语法介绍

  2. MySQL数据类型

  3. MySQL数据SQL查询(数据库、表、存储过程、存储函数、触发器、视图、索引)

  4. MySQL定义变量、条件和流程控制

  5. MySQL聚合函数

1、SQL语法介绍

1、SQL分类

SQL语句,根据其功能,主要分为四类:DDLDMLDQLDCL

DDL(Data Definition Language): 数据定义语言,用来定义数据库对象(数据库,表, 字段)

DML(Data Manipulation Language): 数据操作语言,用来对数据库表中的数据进行增删改

DQL(Data Query Language): 数据查询语言,用来查询数据库中表的记录

DCL(Data Control Language): 数据控制语言,用来创建数据库用户、控制数据库的访问权限

2、SQL书写规则

  • SQL语句可以单行或多行书写,以分号结尾。

  • MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。

  • 在同一个数据库服务器中,不能创建两个名称相同的数据库,否则将会报错。

  • 如果删除一个不存在的数据库,将会报错。

  • 注释:

    • 单行注释:-- 注释内容 或 # 注释内容

    • 多行注释:/* 注释内容 */

2、MySQL数据类型

        MySQL中的数据类型,主要分为三类:数值类型字符串类型日期时间类型

1、数值类型

-- tinyint
大小1byte,有符号范围(-128,127),无符号范围(0,255), 小整数值.

-- smallint
大小2bytes, 有符号范围(-32768,32767), 无符号范围(0,65535),大整数值。

-- mediumint
大小3bytes, 有符号范围(-8388608,8388607),无符号范围(0,16777215),大整数值

-- int/integer
大小4bytes,有符号范围(-2147483648,2147483647),无符号范围(0,4294967295),大整数值

-- bigint
大小8bytes,有符号范围(-2的63次方,2的63次方-1),无符号范围(0,2的64次方-1),极大整数值

-- float
大小4bytes,有符号范围(-3.402823466 E+38, 3.402823466351 E+38),无符号范围0 和 (1.175494351 E-38,3.402823466 E+38),单精度浮点数 值

-- double
大小8bytes,有符号范围(-1.7976931348623157 E+308, 1.7976931348623157 E+308),无符号范围0 和 (2.2250738585072014 E-308, 1.7976931348623157 E+308),双精 度浮 点数 值
-- decimal
有符号范围依赖于M(精度)和D(标度) 的值,无符号范围依赖于M(精度)和D(标度)的 值,小数 值(精 确定 点数)



注:DECIMAL中M(精度)表示整个数值长度,D(标度)表示小数位长度。例如:123.45。M=5,D=2。

2、字符串类型

-- char
大小0-255bytes, 定长字符串(需要指定长度)

-- varchar
大小0-65535bytes, 变长字符串(需要指定长度)

-- tinyblob
大小0-255 bytes, 不超过255个字符的二进制数据

-- tinytext
大小0-255 bytes, 短文本字符串

-- blob
大小0-65 535 bytes,二进制形式的长文本数据

-- text
大小0-65 535 bytes,长文本数据

-- mediumblob
大小0-16 777 215 bytes,二进制形式的中等长度文本数据

-- mediumtext
大小0-16 777 215 bytes, 中等长度文本数据

-- longblob
大小0-4 294 967 295 bytes,二进制形式的极大文本数据

-- longtext
大小0-4 294 967 295 bytes,极大文本数据

注意:char 与 varchar 都可以描述字符串,char是定长字符串,指定长度多长,就占用多少个
字符,和 字段值的长度无关 。而varchar是变长字符串,指定的长度为最大占用长度 。
相对来说,char的性能会更高些,而varchar相对更节省存储空间

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 至 2038-01-19 03:14:07,YYYY-MM-DD HH:MM:SS 混合日期和时 间值,时间戳

MySQL数据SQL查询

1、数据库

-- 新建数据库
语法:CREATE DATABASE [IF NOT EXISTS] <数据库名> [[DEFAULT] CHARACTER SET <字符集名>]  [[DEFAULT] COLLATE <校对规则名>];
示例:
CREATE DATABASE
IF
    NOT EXISTS xuzaiTest CHARACTER 
    SET utf8mb4 COLLATE utf8mb4_general_ci;

-- 查看数据库
语法:SHOW DATABASES [LIKE '数据库名'];
示例:
show databases;
show databases like '%xuzai%';
show create database xuzaiTest; (可查看字符集)

-- 选择数据库    
语法:USE <数据库名>
示例:
use xuzaiTest;

-- 删除数据库
语法:DROP DATABASE [ IF EXISTS ] <数据库名>
示例:
drop database xuzaiTest;

-- 修改数据库
语法:
ALTER DATABASE [数据库名] 
    [ DEFAULT ] CHARACTER SET <字符集名> |
    [ DEFAULT ] COLLATE <校对规则名>;
示例:
alter database xuzaiTest  character set utf8;

2、表

-- 1、创建表
语法:CREATE TABLE <表名> ([表定义选项])[表选项][分区选项];
示例:
 CREATE TABLE  TS_CompareDetailLog
    (
        rec_id                         bigint           DEFAULT 0          NOT NULL,
        fund_id                        bigint           DEFAULT 0          NOT NULL,
        business_date                  int              DEFAULT 0          NOT NULL,
        item_id                        varchar(16)      DEFAULT ''         NOT NULL,
        operate_type                   varchar(2)       DEFAULT ''         COMMENT '数据字典11071',
        comments                       varchar(1000)    DEFAULT ''         NOT NULL,
        user_operate                   varchar(32)      DEFAULT ''         NOT NULL,
        dtime_operate                  decimal(14,6)    DEFAULT 0.0        NOT NULL,
        PRIMARY KEY(rec_id)
    );
示例:
create table TS_CompareDetailLog_20240302 as select * from TS_CompareDetailLog;

-- 2、新增表列
在表尾添加字段
语法1:ALTER TABLE <表名> ADD <新字段名><数据类型>[约束条件];
在表头添加字段
语法2:ALTER TABLE <表名> ADD <新字段名> <数据类型> [约束条件] FIRST;
在表中间添加字段
语法3:ALTER TABLE <表名> ADD <新字段名> <数据类型> [约束条件] AFTER <已经存在的字段名>;



-- 3、修改表
语法:ALTER TABLE <表名> [修改选项]
修改选项:
ADD COLUMN <列名> <类型>
| CHANGE COLUMN <旧列名> <新列名> <新列类型>
| ALTER COLUMN <列名> { SET DEFAULT <默认值> | DROP DEFAULT }
| MODIFY COLUMN <列名> <类型>
| DROP COLUMN <列名>
| RENAME TO <新表名>
| CHARACTER SET <字符集名>
| COLLATE <校对规则名>

示例:
-- 添加列
alter table TS_CompareDetailLog add column testColumn int ;
-- 修改表
-- 修改表的列的名称 
alter table TS_CompareDetailLog change column testColumn  xuzaiColumn int default 0 ;
-- 修改表的列的默认值
alter table TS_CompareDetailLog alter column xuzaiColumn set default 1;
-- 修改表的列的类型
alter table TS_CompareDetailLog MODIFY column xuzaiColumn VARCHAR(2) default '';
-- 修改表的名称
alter table TS_CompareDetailLog_20240302 rename to TS_CompareDetailLog_20240303;
-- 修改表的字符集
ALTER TABLE 表名 [DEFAULT] CHARACTER SET <字符集名> [DEFAULT] COLLATE <校对规则名>;

-- 4、删除列
语法:ALTER TABLE <表名> DROP <字段名>;
alter table TS_CompareDetailLog drop COLUMN xuzaiColumn;


-- 5、删除表
语法:DROP TABLE [IF EXISTS] 表名1 [ ,表名2, 表名3 ...]
示例:
drop table TS_CompareDetailLog_20240303;


删除父表有以下两种方法:
先删除与它关联的子表,再删除父表;但是这样会同时删除两个表中的数据。
将关联表的外键约束取消,再删除父表;适用于需要保留子表的数据,只删除父表的情况。

语法:
ALTER TABLE '子表名称' DROP FOREIGN KEY '外键名称';
drop table tableName;

-- 6、查看表以及表结构
语法:DESCRIBE <表名>; 或者 DESC <表名>;
示例:DESCRIBE TS_CompareDetailLog;
-- 查看表创建sql
show create table TS_CompareDetailLog;

3、存储过程

        通常我们完成一个逻辑功能可能需要多条sql,而且各个语句之间可能需要参数传递,存储过程可以完成这样复杂的逻辑功能。由一组sql语句和控制结构组成。预先编译和优化好,存储在数据库服务器。调用方式:call 存储过程的名称。

特点:
-- 封装性:
存储过程可以把这些 SQL 语句包含到一个独立的单元中,使外界看不到复杂的 SQL 语句,只需要简单调用即可达到目的
-- 可增强 SQL 语句的功能和灵活性:
存储过程可以用流程控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
可减少网络流量:
由于存储过程是在服务器端运行的,且执行速度快,因此当客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而可降低网络负载。
-- 高性能:
当存储过程被成功编译后,就存储在数据库服务器里了,以后客户端可以直接调用,这样所有的 SQL 语句将从服务器执行,从而提高性能。但需要说明的是,存储过程不是越多越好,过多的使用存储过程反而影响系统性能
-- 提高数据库的安全性和数据的完整性:
存储过程提高安全性的一个方案就是把它作为中间组件,存储过程里可以对某些表做相关操作,然后存储过程作为接口提供给外部程序。这样,外部程序无法直接操作数据库表,只能通过存储过程来操作对应的表,因此在一定程度上,安全性是可以得到提高的。
-- 使数据独立:
数据的独立可以达到解耦的效果,也就是说,程序可以调用存储过程,来替代执行多条的 SQL 语句。这种情况下,存储过程把数据同用户隔离开来,优点就是当数据表的结构改变时,调用表不用修改程序,只需要数据库管理者重新编写存储过程即可
-- 1、创建存储过程
CREATE PROCEDURE <过程名> ( [过程参数[,…] ] ) <过程体>
[过程参数[,…] ] 格式
[ IN | OUT | INOUT ] <参数名> <类型>

示例: -- TS_AutoTaskReport 新增字段report_level
DROP PROCEDURE IF EXISTS sp_db_mysql;
DELIMITER $$
CREATE PROCEDURE sp_db_mysql()
BEGIN
    DECLARE v_rowcount INT;
    DECLARE database_name VARCHAR(100);
    SELECT DATABASE() INTO database_name;

    SELECT COUNT(1) INTO v_rowcount FROM information_schema.columns WHERE table_schema= database_name
    AND table_name='TS_AutoTaskReport' AND column_name='report_level';

    IF v_rowcount = 0 THEN
        ALTER TABLE TS_AutoTaskReport ADD report_level varchar(2);
    END IF;
END$$
DELIMITER ;
CALL sp_db_mysql();
DROP PROCEDURE IF EXISTS sp_db_mysql;OCEDURE IF EXISTS sp_db_mysql;


-- 2、查看存储过程
语法:SHOW PROCEDURE STATUS LIKE '存储过程名';
示例:SHOW PROCEDURE STATUS LIKE 'sp_db_mysql';
DELIMITER $$
CREATE PROCEDURE sp_db_mysql()
BEGIN
    select * from TS_CompareDetailLog;
END$$
DELIMITER ;
CALL sp_db_mysql();


-- 3、查看存储过程的定义
语法:SHOW CREATE PROCEDURE 存储过程名;
示例:show create PROCEDURE sp_db_mysql;


存储过程的信息都存储在 information_schema 数据库下的 Routines 表中,可以通过查询该表的记录来查询存储过程的信息,SQL 语句如下

语法:SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME=存储过程名;示例:
示例:
 select * from information_schema.ROUTINES where ROUTINE_NAME = 'sp_db_mysql';


-- 4、修改存储过程语法:
语法:ALTER PROCEDURE 存储过程名 [ 特征 ... ]
【特征】:指定了存储过程的特性,可能的取值有:
CONTAINS SQL 表示子程序包含 SQL 语句,但不包含读或写数据的语句。
NO SQL 表示子程序中不包含 SQL 语句。
READS SQL DATA 表示子程序中包含读数据的语句。
MODIFIES SQL DATA 表示子程序中包含写数据的语句。
SQL SECURITY { DEFINER |INVOKER } 指明谁有权限来执行。
DEFINER 表示只有定义者自己才能够执行。
INVOKER 表示调用者可以执行。
COMMENT 'string' 表示注释信息。


ALTER PROCEDURE 语句用于修改存储过程的某些特征。如果要修改存储过程的内容,可以先删除原存储过程,再以相同的命名创建新的存储过程;如果要修改存储过程的名称,可以先删除原存储过程,再以不同的命名创建新的存储过程



-- 5、删除存储过程
语法:DROP PROCEDURE [ IF EXISTS ] <过程名>
drop procedure if exists 'showStuScore';
SELECT * FROM information_schema.routines WHERE routine_name='ShowStuScore';

4、存储函数

        存储函数和存储过程一样,都是在数据库中定义一些 SQL 语句的集合。存储函数可以通过 return 语句返回函数值,主要用于计算并返回一个值。而存储过程没有直接返回值,主要用于执行操作.

-- 1、创建存储函数
CREATE FUNCTION sp_name ([func_parameter[...]])
RETURNS type
[characteristic ...] routine_boby

其中:
sp_name 参数:表示存储函数的名称;
func_parameter:表示存储函数的参数列表;
RETURNS type:指定返回值的类型;
characteristic 参数:指定存储函数的特性,该参数的取值与存储过程是一样的;
routine_body 参数:表示 SQL 代码的内容,可以用 BEGIN...END 来标示 SQL 代码的开始和结束。


在具体创建函数时,函数名不能与已经存在的函数名重名。除了上述要求外,推荐函数名命名(标识符)为 function_xxx 或者 func_xxx
func_parameter 可以由多个参数组成,其中每个参数由参数名称和参数类型组成,其形式如下:
[IN | OUT | INOUT] param_name type;
其中:
IN 表示输入参数,OUT 表示输出参数,INOUT 表示既可以输入也可以输出;
param_name 参数是存储函数的参数名称;
type 参数指定存储函数的参数类型,该类型可以是 MySQL 数据库的任意数据类型


示例:
DELIMITER $$
CREATE FUNCTION sp_db_mysql(business_date int(8))
returns int(8)
COMMENT '返回业务日期'
BEGIN
    return(select distinct business_date  from TS_CompareDetailLog where business_date = business_date);
END$$
DELIMITER ;  


-- 2、调用存储函数
select 函数名称(参数);

-- 3、查看存储函数:
SHOW FUNCTION STATUS LIKE 存储函数名;
SHOW CREATE FUNCTION 存储函数名;
SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME=存储函数名; 

-- 4、删除存储函数
DROP FUNCTION [ IF EXISTS ] <函数名> 

-- 5、修改存储函数:
ALTER FUNCTION 存储函数名 [ 特征 ... ] 
存储函数的特征与存储过程的基本一样。

5、触发器

        MySQL 的触发器和存储过程一样,都是嵌入到 MySQL 中的一段程序,是 MySQL 中管理数据的有力工具。不同的是执行存储过程要使用 CALL 语句来调用,而触发器的执行不需要使用 CALL 语句来调用,也不需要手工启动,而是通过对数据表的相关操作来触发、激活从而实现执行。比如当对 student 表进行操作(INSERT,DELETE 或 UPDATE)时就会激活它执行。

        触发器与数据表关系密切,主要用于保护表中的数据。特别是当有多个表具有一定的相互联系的时候,触发器能够让不同的表保持数据的一致性。

在 MySQL 中,只有执行 INSERT、UPDATE 和 DELETE 操作时才能激活触发器,其它 SQL 语句则不会激活触发器。

触发器的优点如下:

  • 触发器的执行是自动的,当对触发器相关表的数据做出相应的修改后立即执行。
  • 触发器可以实施比 FOREIGN KEY 约束、CHECK 约束更为复杂的检查和操作。
  • 触发器可以实现表数据的级联更改,在一定程度上保证了数据的完整性。

触发器的缺点如下:

  • 使用触发器实现的业务逻辑在出现问题时很难进行定位,特别是涉及到多个触发器的情况下,会使后期维护变得困难。
  • 大量使用触发器容易导致代码结构被打乱,增加了程序的复杂性,
  • 如果需要变动的数据量较大时,触发器的执行效率会非常低。
-- 触发器种类
MySQL 所支持的触发器有三种:INSERT 发器、UPDATE 触发器和 DELETE 触发器。

-- INSERT触发器
使用 INSERT 触发器需要注意以下几点:
1、在 INSERT 触发器代码内,可引用一个名为 NEW(不区分大小写)的虚拟表来访问被插入的行。
2、在 BEFORE INSERT 触发器中,NEW 中的值也可以被更新,即允许更改被插入的值(只要具有对应的操作权限)。
3、对于 AUTO_INCREMENT 列,NEW 在 INSERT 执行之前包含的值是 0,在 INSERT 执行之后将包含新的自动生成值 



-- UPDATE 触发器
在 UPDATE 语句执行之前或之后响应的触发器。

使用 UPDATE 触发器需要注意以下几点:
1、在 UPDATE 触发器代码内,可引用一个名为 NEW(不区分大小写)的虚拟表来访问更新的值。
2、在 UPDATE 触发器代码内,可引用一个名为 OLD(不区分大小写)的虚拟表来访问 UPDATE 语句执行前的值。
3、在 BEFORE UPDATE 触发器中,NEW 中的值可能也被更新,即允许更改将要用于 UPDATE 语句中的值(只要具有对应的操作权限)。
4、OLD 中的值全部是只读的,不能被更新。 



-- DELETE 触发器

在 DELETE 语句执行之前或之后响应的触发器。

使用 DELETE 触发器需要注意以下几点:
1、在 DELETE 触发器代码内,可以引用一个名为 OLD(不区分大小写)的虚拟表来访问被删除的行。
2、OLD 中的值全部是只读的,不能被更新。 


对于事务性表,如果触发程序失败,以及由此导致的整个语句失败,那么该语句所执行的所有更改将回滚;对于非事务性表,则不能执行此类回滚,即使语句失败,失败之前所做的任何更改依然有效。

若 BEFORE 触发程序失败,则 MySQL 将不执行相应行上的操作。

若在 BEFORE 或 AFTER 触发程序的执行过程中出现错误,则将导致调用触发程序的整个语句失败。

仅当 BEFORE 触发程序和行操作均已被成功执行,MySQL 才会执行 AFTER 触发程序。 

        触发器是与 MySQL 数据表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性

-- 创建触发器
CREATE <触发器名> < BEFORE | AFTER >
<INSERT | UPDATE | DELETE >
ON <表名> FOR EACH Row<触发器主体> 


解释:
1)触发器名称
触发器的名称,触发器在当前数据库中必须具有唯一的名称。如果要在某个特定数据库中创建,名称前面应该加上数据库的名称

2)INSERT | UPDATE | DELETE
触发事件,用于指定激活触发器的语句的种类。
注意:三种触发器的执行时间如下。
INSERT:将新行插入表时激活触发器。例如,INSERT 的 BEFORE 触发器不仅能被 MySQL 的 INSERT 语句激活,也能被 LOAD DATA 语句激活。
DELETE: 从表中删除某一行数据时激活触发器,例如 DELETE 和 REPLACE 语句。
UPDATE:更改表中某一行数据时激活触发器,例如 UPDATE 语句。

3)BEFORE | AFTER 
BEFORE 和 AFTER,触发器被触发的时刻,表示触发器是在激活它的语句之前或之后触发。
若希望验证新数据是否满足条件,则使用 BEFORE 选项;若希望在激活触发器的语句执行之后完成几个或更多的改变,则通常使用 AFTER 选项


4)表名
与触发器相关联的表名,此表必须是永久性表,不能将触发器与临时表或视图关联起来。
同一个表不能拥有两个具有相同触发时刻和事件的触发器

5) 触发器主体
触发器动作主体,包含触发器激活时将要执行的 MySQL 语句。如果要执行多个语句,可使用 BEGIN…END 复合语句结构 

6)FOR EACH ROW 
一般是指行级触发,对于受触发事件影响的每一行都要激活触发器的动作。例如,使用 INSERT 语句
向某个表中插入多行数据时,触发器会对每一行数据的插入都执行相应的触发器动作


-- 创建触发器
示例1:创建一个名为 SumOfSalary 的触发器,触发的条件是向数据表 tb_emp8 中插入数据之前,对新插入的 salary 字段值进行求和计算。输入的 SQL 语句和执行过程如下所示
CREATE TRIGGER SumOfSalary
BEFORE INSERT ON tb_emp8
FOR EACH ROW
SET @sum=@sum+NEW.salary;


示例2:创建一个名为 double_salary 的触发器,触发的条件是向数据表 tb_emp6 中插入数据之后,再向数据表 tb_emp7 中插入相同的数据,并且 salary 为 tb_emp6 中新插入的 salary 字段值的 2 倍。
CREATE TRIGGER double_salary
AFTER INSERT ON tb_emp6
FOR EACH ROW
INSERT INTO tb_emp7 VALUES (NEW.id,NEW.name,deptId,2*NEW.salary);


-- 查看触发器
SHOW TRIGGERS;
SELECT * FROM information_schema.triggers WHERE trigger_name= '触发器名';
SELECT * FROM information_schema.triggers \G
mysql> SHOW TRIGGERS \G


-- 删除触发器
DROP TRIGGER [ IF EXISTS ] [数据库名] <触发器名>
执行 DROP TRIGGER 语句需要 SUPER 权限。
[数据库名称]可选项。指定触发器所在的数据库的名称。若没有指定,则为当前默认的数据库。

6、视图

        MySQL 视图(View)是一种虚拟存在的表,同真实表一样,视图也由列和行构成,但视图并不实际存在于数据库中。行和列的数据来自于定义视图的查询中所使用的表,并且还是在使用视图时动态生成的。

        数据库中只存放了视图的定义,并没有存放视图中的数据,这些数据都存放在定义视图查询所引用的真实表中。使用视图查询数据时,数据库会从真实表中取出对应的数据。因此,视图中的数据是依赖于真实表中的数据的。一旦真实表中的数据发生改变,显示在视图中的数据也会发生改变。

        视图可以从原有的表上选取对用户有用的信息,那些对用户没用,或者用户没有权限了解的信息,都可以直接屏蔽掉,作用类似于筛选。这样做既使应用简单化,也保证了系统的安全       

-- 视图并不同于数据表,它们的区别在于以下几点:
1、视图不是数据库中真实的表,而是一张虚拟表,其结构和数据是建立在对数据中真实表的查询基础上的。
2、存储在数据库中的查询操作 SQL 语句定义了视图的内容,列数据和行数据来自于视图查询所引用的实际表,引用视图时动态生成这些数据。
3、视图没有实际的物理记录,不是以数据集的形式存储在数据库中的,它所对应的数据实际上是存储在视图所引用的真实表中的。
4、视图是数据的窗口,而表是内容。表是实际数据的存放单位,而视图只是以不同的显示方式展示数据,其数据来源还是实际表。
5、视图是查看数据表的一种方法,可以查询数据表中某些字段构成的数据,只是一些 SQL 语句的集合。从安全的角度来看,视图的数据安全性更高,使用视图的用户不接触数据表,不知道表结构。
6、视图的建立和删除只影响视图本身,不影响对应的基本表。


-- 视图的优点
视图与表在本质上虽然不相同,但视图经过定义以后,结构形式和表一样,可以进行查询、修改、
更新和删除等操作。同时,视图具有如下优点:

1):定制用户数据,聚焦特定的数据
2):简化数据操作
3):提高数据的安全性
4):共享所需数据:
5):更改数据格式:通过使用视图,可以重新格式化检索出的数据
6):重用 SQL 语句


使用视图的时候,还应该注意以下几点:
1、创建视图需要足够的访问权限。
2、创建视图的数目没有限制。
3、视图可以嵌套,即从其他视图中检索数据的查询来创建视图。
4、视图不能索引,也不能有关联的触发器、默认值或规则。
5、视图可以和表一起使用。
6、视图不包含数据,所以每次使用视图时,都必须执行查询中所需的任何一个检索操作。如果用多个连接和过滤条件创建了复杂的视图或嵌套了视图,可能会发现系统运行性能下降得十分严重。因此,在部署大量视图应用时,应该进行系统测试。


-- 创建视图
语法: CREATE VIEW <视图名> AS <SELECT语句>

对于创建视图中的 SELECT 语句的指定存在以下限制:
用户除了拥有 CREATE VIEW 权限外,还具有操作中涉及的基础表和其他视图的相关权限。
SELECT 语句不能引用系统或用户变量。
SELECT 语句不能包含 FROM 子句中的子查询。
SELECT 语句不能引用预处理语句参数。 
示例:
CREATE VIEW view_students_info
AS SELECT * FROM tb_students_info;

-- 查询视图
DESCRIBE 视图名; 或者 DESC 视图名;
-- 查看视图的详细信息
SHOW CREATE VIEW 视图名;

-- 查询视图
所有视图的定义都是存储在 information_schema 数据库下的 views 表中,也可以在这个表中查看所有视图的详细信息,SQL 语句如下:
SELECT * FROM information_schema.views;


-- 修改视图
语法:ALTER VIEW <视图名> AS <SELECT语句>
视图是一个虚拟表,实际的数据来自于基本表,所以通过插入、修改和删除操作更新视图中的数据,
实质上是在更新视图所引用的基本表的数据。某些视图是可更新的。也就是说,可以使用 UPDATE、DELETE 或 INSERT 等语句更新基本表的内容


-- 不可更新视图:
还有一些特定的其他结构,这些结构会使得视图不可更新。更具体地讲,如果视图包含以下结构中的任何一种,它就是不可更新的
聚合函数 SUM()、MIN()、MAX()、COUNT() 等。
DISTINCT 关键字。
GROUP BY 子句。
HAVING 子句。
UNION 或 UNION ALL 运算符。
位于选择列表中的子查询。
FROM 子句中的不可更新视图或包含多个表。
WHERE 子句中的子查询,引用 FROM 子句中的表。
ALGORITHM 选项为 TEMPTABLE(使用临时表总会使视图成为不可更新的)的时候 

-- 删除视图
语法:DROP VIEW <视图名1> [ , <视图名2> …]

7、索引

索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,可以用来快速查询数据表中有某一特定值的记录。

索引有其明显的优势,也有其不可避免的缺点。

优点

索引的优点如下:

  • 通过创建唯一索引可以保证数据库表中每一行数据的唯一性。
  • 可以给所有的 MySQL 列类型设置索引。
  • 可以大大加快数据的查询速度,这是使用索引最主要的原因。
  • 在实现数据的参考完整性方面可以加速表与表之间的连接。
  • 在使用分组和排序子句进行数据查询时也可以显著减少查询中分组和排序的时间

缺点

增加索引也有许多不利的方面,主要如下:

  • 创建和维护索引组要耗费时间,并且随着数据量的增加所耗费的时间也会增加。
  • 索引需要占磁盘空间,除了数据表占数据空间以外,每一个索引还要占一定的物理空间。如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。
  • 当对表中的数据进行增加、删除和修改的时候,索引也要动态维护,这样就降低了数据的维护速度。
-- 创建索引
语法1:CREATE <索引名> ON <表名> (<列名> [<长度>] [ ASC | DESC])

语法说明如下:
<索引名>:指定索引名。一个表可以创建多个索引,但每个索引在该表中的名称是唯一的。
<表名>:指定要创建索引的表名。
<列名>:指定要创建索引的列名。通常可以考虑将查询语句中在 JOIN 子句和 WHERE 子句里经常出现的列作为索引列。
<长度>:可选项。指定使用列前的 length 个字符来创建索引。使用列的一部分创建索引有利于减小索引文件的大小,节省索引列所占的空间。 

索引也可以在创建表(CREATE TABLE)的同时创建。在 CREATE TABLE 语句中添加以下语句

语法2:在 CREATE TABLE 语句中添加此语句,表示在创建新表的同时创建该表的主键
CONSTRAINT PRIMARY KEY [索引类型] (<列名>,…)

语法3:在 CREATE TABLE 语句中添加此语句,表示在创建新表的同时创建该表的索引
KEY | INDEX [<索引名>] [<索引类型>] (<列名>,…)

语法4:在 CREATE TABLE 语句中添加此语句,表示在创建新表的同时创建该表的唯一性索引
UNIQUE [ INDEX | KEY] [<索引名>] [<索引类型>] (<列名>,…)

语法5:在 CREATE TABLE 语句中添加此语句,表示在创建新表的同时创建该表的外键
FOREIGN KEY <索引名> <列名>

语法6:修改表的同时为该表添加索引
ALTER TABLE ADD INDEX [<索引名>] [<索引类型>] (<列名>,…)

语法7:在修改表的同时为该表添加主键
ALTER TABLE ADD PRIMARY KEY [<索引类型>] (<列名>,…)

语法8:在修改表的同时为该表添加外键。
ALTER TABLE ADD FOREIGN KEY [<索引名>] (<列名>,…)


示例:
1、创建普通索引:创建普通索引时,通常使用 INDEX 关键字。
CREATE TABLE tb_stu_info(
id INT NOT NULL,
name CHAR(45) DEFAULT NULL,
dept_id INT DEFAULT NULL,
age INT DEFAULT NULL,
height INT DEFAULT NULL,
INDEX(height)
);

2、创建唯一索引
CREATE TABLE tb_stu_info2(
id INT NOT NULL,
name CHAR(45) DEFAULT NULL,
dept_id INT DEFAULT NULL,
age INT DEFAULT NULL,
height INT DEFAULT NULL,
UNIQUE INDEX(height)
);

-- 查看索引
语法:SHOW INDEX FROM <表名> [ FROM <数据库名>]

-- 删除索引
语法1:DROP INDEX <索引名> ON <表名>
语法2:ALTER TABLE DROP PRIMARY KEY:表示删除表中的主键。一个表只有一个主键,主键也是一个索引。   
语法3:ALTER TABLE DROP INDEX index_name 表示删除名称为 index_name 的索引。
语法4: ALTER TABLE DROP FOREIGN KEY fk_symbol 删除外键。

MySQL定义变量、条件和流程控制

     在 MySQL 中,除了支持标准的存储过程和函数外,还引入了表达式。表达式与其它高级语言的表达式一样,由变量、运算符和流程控制来构成。

变量是表达式语句中最基本的元素,可以用来临时存储数据。在存储过程和函数中都可以定义和使用变量。用户可以使用 DECLARE 关键字来定义变量,定义后可以为变量赋值。这些变量的作用范围是 BEGIN...END 程序段中

-- 定义变量
语法:DECLARE var_name[,...] type [DEFAULT value] 
其中:
DECLARE 关键字是用来声明变量的;
var_name 参数是变量的名称,这里可以同时定义多个变量;
type 参数用来指定变量的类型;
DEFAULT value 子句将变量默认值设置为 value,没有使用 DEFAULT 子句时,默认值为 NULL。 
示例:
DECLARE my_sql INT DEFAULT 10; 

-- 为变量赋值
MySQL 中可以使用 SET 关键字来为变量赋值,SET 语句的基本语法如下:
语法1:SET var_name = expr[,var_name = expr]... 
其中:
SET 关键字用来为变量赋值;
var_name 参数是变量的名称;
expr 参数是赋值表达式。
示例:
 SET my_sql=30;

语法2:SELECT col_name [...] INTO var_name[,...] FROM table_name WEHRE condition
其中:
col_name 参数表示查询的字段名称;
var_name 参数是变量的名称;
table_name 参数指表的名称;
condition 参数指查询条件。
示例:
SELECT id INTO my_sql FROM tb_student WEHRE id=2;



-- 定义条件
MySQL 中可以使用 DECLARE 关键字来定义条件。其基本语法如下:
DECLARE condition_name CONDITION FOR condition_value
condition value:
SQLSTATE [VALUE] sqlstate_value | mysql_error_code 

其中:
condition_name 参数表示条件的名称;
condition_value 参数表示条件的类型;
sqlstate_value 参数和 mysql_error_code 参数都可以表示 MySQL 的错误。
sqlstate_value 表示长度为 5 的字符串类型错误代码 

示例:
//方法一:使用sqlstate_value
DECLARE can_not_find CONDITION FOR SQLSTATE '42S02';

//方法二:使用 mysql_error_code
DECLARE can_not_find CONDITION FOR 1146;

-- 定义处理程序
MySQL 中可以使用 DECLARE 关键字来定义处理程序。其基本语法如下:
DECLARE handler_type HANDLER FOR condition_value[...] sp_statement。

参数说明:
handler_type:
CONTINUE | EXIT | UNDO
condition_value:
SQLSTATE [VALUE] sqlstate_value | condition_name | SQLWARNING | NOT FOUND | SQLEXCEPTION | mysql_error_code 


其中,handler_type 参数指明错误的处理方式,该参数有 3 个取值。这 3 个取值分别是 CONTINUE、EXIT 和 UNDO。
CONTINUE 表示遇到错误不进行处理,继续向下执行;
EXIT 表示遇到错误后马上退出;
UNDO 表示遇到错误后撤回之前的操作,MySQL 中暂时还不支持这种处理方式 


注意:通常情况下,执行过程中遇到错误应该立刻停止执行下面的语句,并且撤回前面的操作。
但是,MySQL 中现在还不能支持 UNDO 操作。因此,遇到错误时最好执行 EXIT 操作。
如果事先能够预测错误类型,并且进行相应的处理,那么可以执行 CONTINUE 操作。

参数指明错误类型,该参数有 6 个取值:
sqlstate_value:包含 5 个字符的字符串错误值;
condition_name:表示 DECLARE 定义的错误条件名称;
SQLWARNING:匹配所有以 01 开头的 sqlstate_value 值;
NOT FOUND:匹配所有以 02 开头的 sqlstate_value 值;
SQLEXCEPTION:匹配所有没有被 SQLWARNING 或 NOT FOUND 捕获的 sqlstate_value 值;
mysql_error_code:匹配数值类型错误代码。

sp_statement 参数为程序语句段,表示在遇到定义的错误时,需要执行的一些存储过程或函数


示例:
//方法一:捕获 sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info='CAN NOT FIND'; 
捕获 sqlstate_value 值。如果遇到 sqlstate_value 值为 42S02,执行 CONTINUE 操作,并且输出“CAN NOT FIND”信息。

//方法二:捕获 mysql_error_code
DECLARE CONTINUE HANDLER FOR 1146 SET @info='CAN NOT FIND'; 
捕获 mysql_error_code 值。如果遇到 mysql_error_code 值为 1146, 执行 CONTINUE 操作,并且输出“CAN NOT FIND”信息

//方法三:先定义条件,然后调用
DECLARE can_not_find CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR can_not_find SET @info='CAN NOT FIND'; 
先定义条件,然后再调用条件。这里先定义 can_not_find 条件,遇到 1146 错误就执行 CONTINUE 操作。


//方法四:使用 SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR'; 
使用 SQLWARNING。SQLWARNING 捕获所有以 01 开头的 sqlstate_value 值,然后执行 EXIT 操作,并且输出“ERROR"信息。

//方法五:使用 NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info='CAN NOT FIND'; 
使用 NOT FOUND。NOT FOUND 捕获所有以 02 开头的 sqlstate_value 值,然后执行 EXIT 操作,并且输出“CAN NOT FIND”信息。

//方法六:使用 SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR'; 
使用 SQLEXCEPTION。 SQLEXCEPTION 捕获所有没有被 SQLWARNING 或 NOT FOUND 捕获的 sqlstate_value 值,然后执行 EXIT 操作,并且输出“ERROR”信息。

1、控制语句

        在存储过程和自定义函数中可以使用流程控制语句来控制程序的流程。MySQL 中流程控制语句有:IF 语句、CASE 语句、LOOP 语句、LEAVE 语句、ITERATE 语句、REPEAT 语句和 WHILE 语句等。

-- if
IF 语句用来进行条件判断,根据是否满足条件(可包含多个条件),来执行不同的语句,是流程控制中最常用的判断语句。其语法的基本形式如下:
语法:
IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list]...
    [ELSE statement_list]
END IF 

其中,search_condition 参数表示条件判断语句,如果返回值为 TRUE ,相应的 SQL 语句列表(statement_list)被执行;如果返回值为 FALSE,则 ELSE 子句的语句列表被执行。statement_list 可以包括一个或多个语句。


-- case
CASE 语句也是用来进行条件判断的,它提供了多个条件进行选择,可以实现比 IF 语句更复杂的条件判断。CASE 语句的基本形式如下: 
语法:
CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list]...
    [ELSE statement_list]
END CASE 
其中:
case_value 参数表示条件判断的变量,决定了哪一个 WHEN 子句会被执行;
when_value 参数表示变量的取值,如果某个 when_value 表达式与 case_value 变量的值相同,则执行对应的 THEN 关键字后的 statement_list 中的语句;
statement_list 参数表示 when_value 值没有与 case_value 相同值时的执行语句。
CASE 语句都要使用 END CASE 结束。 

示例:
CASE age
    WHEN 20 THEN SET @count1=@count1+1;
    ELSE SET @count2=@count2+1;
END CASE;

CASE 语句还有另一种形式。该形式的语法如下:
语法: 
CASE
    WHEN search_condition THEN statement_list
    [WHEN search_condition THEN statement_list] ...
    [ELSE statement_list]
END CASE  

其中,search_condition 参数表示条件判断语句;statement_list 参数表示不同条件的执行语句。 
示例:
CASE
    WHEN age=20 THEN SET @count1=@count1+1;
    ELSE SET @count2=@count2+1;
END CASE; 


-- Loop
LOOP 语句可以使某些特定的语句重复执行。与 IF 和 CASE 语句相比,LOOP 只实现了一个简单的循环,并不进行条件判断。 
LOOP 语句本身没有停止循环的语句,必须使用 LEAVE 语句等才能停止循环,跳出循环过程。LOOP 语句的基本形式如下: 
语法:
[begin_label:]LOOP
    statement_list
END LOOP [end_label]
其中,begin_label 参数和 end_label 参数分别表示循环开始和结束的标志,这两个标志必须相同,而且都可以省略;statement_list 参数表示需要循环执行的语句。

示例:
add_num:LOOP
    SET @count=@count+1;
END LOOP add_num;  


-- Leave
LEAVE 语句主要用于跳出循环控制。其语法形式如下:、
语法:
LEAVE label 
其中,label 参数表示循环的标志,LEAVE 语句必须跟在循环标志前面。其中,label 参数表示循环的标志,LEAVE 语句必须跟在循环标志前面。 
示例:
add_num:LOOP
    SET @count=@count+1;
    IF @count=100 THEN
        LEAVE add_num;
END LOOP add num; 


-- iterate 
ITERATE 是“再次循环”的意思,用来跳出本次循环,直接进入下一次循环。ITERATE 语句的基本语法形式如下:
语法:
ITERATE label
其中,label 参数表示循环的标志,ITERATE 语句必须跟在循环标志前面。
示例:
add_num:LOOP
    SET @count=@count+1;
    IF @count=100 THEN
        LEAVE add_num;
    ELSE IF MOD(@count,3)=0 THEN
        ITERATE add_num;
    SELECT * FROM employee;
END LOOP add_num; 
该示例循环执行 count 加 1 的操作,count 值为 100 时结束循环。如果 count 的值能够整除 3,则跳出本次循环,不再执行下面的 SELECT 语句


-- repeat
REPEAT 语句是有条件控制的循环语句,每次语句执行完毕后,会对条件表达式进行判断,
如果表达式返回值为 TRUE,则循环结束,否则重复执行循环中的语句.
语法:
[begin_label:] REPEAT
    statement_list
    UNTIL search_condition
END REPEAT [end_label] 

其中:
begin_label 为 REPEAT 语句的标注名称,该参数可以省略;
REPEAT 语句内的语句被重复,直至 search_condition 返回值为 TRUE。
statement_list 参数表示循环的执行语句;
search_condition 参数表示结束循环的条件,满足该条件时循环结束。
REPEAT 循环都用 END REPEAT 结束。 
示例:
REPEAT
    SET @count=@count+1;
    UNTIL @count=100
END REPEAT; 
该示例循环执行 count 加 1 的操作,count 值为 100 时结束循环。 


-- while
WHILE 语句也是有条件控制的循环语句。WHILE 语句和 REPEAT 语句不同的是,WHILE 语句是当满足条件时,执行循环内的语句,否则退出循环。WHILE 语句的基本语法形式如下: 
语法:
[begin_label:] WHILE search_condition DO
    statement list
END WHILE [end label] 
其中,search_condition 参数表示循环执行的条件,满足该条件时循环执行;statement_list 参数表示循环的执行语句。WHILE 循环需要使用 END WHILE 来结束。 
示例:
WHILE @count<100 DO
    SET @count=@count+1;
END WHILE;

MySQL聚合函数

-- 1、count() : 
SELECT COUNT(`字段名`) FROM `表名`

count('字段'):指定字段,会自动忽略这个字段中的null值,然后输出有值的行数
count(*): 不指定字段,输出这个表的行,不忽略null
count(1): 不指定字段,输出这个表的行,不忽略null, 和count(*)效果一样。


-- 2、sum('字段') 求和,某一列的和
-- 3、avg('字段') 求平均值,某一列的平均值
-- 4、max('字段') 求某一列的最大值
-- 5、concat('参数1', '参数2'); 连接字符串函数
-- 6、length('参数'); 一个汉字返回3
-- 7、截取函数left/right/substring 截取字符串的某段
-- 8、去除空格ltrim/rtrim/trim  去除左侧/右侧/两侧的空格
-- 9、round(参数,n);对参数保留n位小数
-- 10、随机数rand();产生一个0-1的随机数。
-- 11、current_date(); 返回当前日期
-- 12、current_time(); 返回当前时间
-- 13、now(); 返回日期和时间
end
  • 作者:旭仔(联系作者)
  • 发表时间:2024-03-12 22:09
  • 版权声明:自由转载-非商用-非衍生-保持署名
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 公众号转载:请在文末添加作者公众号二维码(公众号二维码见右边,欢迎关注)
  • 评论