MySQL 安装、配置

MySQL安装完成后,需要注意版本差异。在MySQL5.7中,默认数据库编码字符集为latin1
image.png
image.png
不支持中文,需要修改配置my.ini

  1. default-character-set=utf8 #默认字符集
  2. [mysqld] # 大概在76行左右,在其下添加
  3. ...
  4. character-set-server=utf8
  5. collation-server=utf8_general_ci

image.png

SQL语句

SQL语言分类

DDL (Data Definition Language 数据定义语言)

  • 描述:DDL语句定义了不同的数据库、表、视图、索引等数据库对象,还可以用来创建、删除、修改数据库和数据表的结构。
  • 主要语句关键字:CREATE、DROP、ALTER

    DML(Data Manipulation Language 数据操作语言)

  • :DML语句用于添加、删除、更新和查询数据库记录,并检查数据完整性。

  • 主要语句关键字:INSERT、DELETE、UPDATE、SELECT

    DCM(Data Control Language 数据控制语言)

  • 描述:DCM语句用于定义数据库、表、字段、用户的访问权限和安全级别。

  • 主要语句关键字:GRANT、REVOKE、COMMIT、ROLLBACK、SAVEPOINT

    SQL语言规则与规范

    SQL的规则 ——必须要遵守

  • SQL 可以写在一行或者多行。为了提高可读性,各子句分行写,必要时使用缩进

  • 每条命令以 ; 或 \g 或 \G 结束
  • 关键字不能被缩写也不能分行
  • 关于标点符号

    • 必须保证所有的()、单引号、双引号是成对结束的
    • 必须使用英文状态下的半角输入方式
    • 字符串型和日期时间类型的数据可以使用单引号(’ ‘)表示
    • 列的别名,尽量使用双引号(” “),而且不建议省略as

      SQL的规范 ——建议遵守

  • MySQL 在 Windows 环境下是大小写不敏感的

  • MySQL 在 Linux 环境下是大小写敏感的
    • 数据库名、表名、表的别名、变量名是严格区分大小写的
    • 关键字、函数名、列名(或字段名)、列的别名(字段的别名) 是忽略大小写的。
  • 推荐采用统一的书写规范:

    • 数据库名、表名、表别名、字段名、字段别名等都小写
    • SQL 关键字、函数名、绑定变量等都大写

      SQL注释规则

      -- 单行注释:#注释文字(MySQL特有的方式)
      -- 单行注释:-- 注释文字(--后面必须包含一个空格。)
      -- 多行注释:/* 注释文字 */
      

      命名规则规则

  • 数据库、表名不得超过30个字符,变量名限制为29个

  • 必须只能包含A–Z, a–z, 0–9, _共63个字符
  • 数据库名、表名、字段名等对象名中间不要包含空格
  • 同一个MySQL软件中,数据库不能同名;同一个库中,表不能重名;同一个表中,字段不能重名
  • 必须保证你的字段没有和保留字、数据库系统或常用方法冲突。如果坚持使用,请在SQL语句中使用`(着重号)引起来
  • 保持字段名和类型的一致性,在命名字段并为其指定数据类型的时候一定要保证一致性。假如数据类型在一个表里是整数,那在另一个表里可就别变成字符型了

    导入数据库语句

    在命令行客户端登录mysql,使用source指令导入
    source d:\mysqldb.sql
    

    DML - SELECT语句

    SELECT  字段
    FROM  表
    WHERE 过滤条件
    

    查询使用运算符

    第04章_运算符.pdf

    排序与分页

    ```sql SELECT 字段 FROM 表 LIMIT [位置偏移量,] 行数 — 分页查询 WHERE 过滤条件 ORDER BY 字段 ASC|DESC — ASC 升序,DESC 降序

— MySQL 8.0中可以使用“LIMIT 3 OFFSET 4”,意思是获取从第5条记录开始后面的3条记录,和“LIMIT 4,3;”返回的结果相同。

**分页显式公式:**(当前页数-1)*每页条数,每页条数
```sql
SELECT * FROM table
LIMIT (PageNo - 1)*PageSize,PageSize;

使用LIMIT语句约束返回结果的数量,可以减少数据表的网络传输量,也可以提升查询效率。如果我们知道返回结果只有1条,就可以使用LIMIT1,告诉SELECT语句只需要返回一条记录即可。这样的好处就是SELECT不需要扫描完整的表,只需要检索到一条符合条件的记录即可返回。
不同数据库之间LIMIT关键字区别:
在MySQL、PostgreSQL、MariaDB和SQLite中使用LIMIT关键字,而且需要放到SELECT语句的最后面。

  • 如果是SQL Server和Access,需要使用TOP关键字

    SELECT TOP 5 name, hp_max FROM heros ORDER BY hp_max DESC
    
  • 如果是DB2,使用FETCHFIRST5ROWSONLY这样的关键字

    SELECT name, hp_max FROM heros ORDER BY hp_max DESC FETCH FIRST 5 ROWS ONLY
    
  • 如果是Oracle,你需要基于ROWNUM来统计行数

    SELECT rownum,last_name,salary FROM employees WHERE rownum < 5 ORDER BY salary DESC;
    

    多表查询

    SQL92语法使用=来连接条件

    SELECT table1.column, table2.column
    FROM table1, table2
    WHERE table1.column1 = table2.column2; #连接条件
    
  • 等值连接、非等值连接

  • 自然连接、非自然连接
  • 内连接、外连接
    • 内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行
    • 外连接:两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行,这种连接称为左(或右)外连接。没有匹配的行时,结果表中相应的列为空(NULL)。
      • 如果是左外连接,则连接条件中左边的表也称为主表,右边的表称为从表。
      • 如果是右外连接,则连接条件中右边的表也称为主表,左边的表称为从表。

补充:在SQL92中采用(+)代表从表所在的位置。即左或右外连接中,(+)表示哪个是从表。Oracle对SQL92支持较好,而MySQL则不支持SQL92的外连接。在SQL92中,只有左外连接和右外连接,没有满(或全)外连接。

-- 左外连接
SELECT last_name,department_name
FROM employees ,departments
WHERE employees.department_id = departments.department_id(+);
-- 右外连接
SELECT last_name,department_name
FROM employees ,departments
WHERE employees.department_id(+) = departments.department_id;

SQL99语法使用JOIN关键字

SELECT table1.column, table2.column,table3.column
FROM table1
JOIN table2 ON table1 和 table2 的连接条件
JOIN table3 ON table2 和 table3 的连接条件
WHERE 过滤条件



-- INNER JOIN
SELECT 字段列表
FROM A表 INNER JOIN B表
ON 关联条件
WHERE 等其他子句

-- LEFT OUTER JOIN
SELECT 字段列表
FROM A表 LEFT JOIN B表
ON 关联条件
WHERE 等其他子句

-- RIGHT OUTER JOIN
SELECT 字段列表
FROM A表 RIGHT JOIN B表
ON 关联条件
WHERE 等其他子句

语法说明:

  • 可以使用ON子句指定额外的连接条件。
  • 这个连接条件是与其它条件分开的。
  • ON子句使语句具有更高的易读性。
  • 关键字JOIN、INNER JOIN、CROSS JOIN的含义是一样的,都表示内连接

注:满外连接(FULL OUTER JOIN)
满外连接的结果=左右表匹配的数据+左表没有匹配到的数据+右表没有匹配到的数据。SQL99是支持满外连接的。使用FULL JOIN或FULL OUTER JOIN来实现。需要注意的是,MySQL不支持FULL JOIN,但是可以用 LEFT JOIN UNION RIGHT JOIN 代替。

UNION关键字

合并查询结果利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同,并且相互对应。各个SELECT语句之间使用UNION或UNION ALL关键字分隔。

SELECT column,... FROM table1
UNION [ALL]
SELECT column,... FROM ta

注意:执行UNION ALL语句时所需要的资源比UNION语句少。如果明确知道合并数据后的结果数据不存在重复数据,或者不需要去除重复的数据,则尽量使用UNION ALL语句,以提高数据查询的效率。

SQL99语法新特性

自然连接

SQL99在SQL92的基础上提供了一些特殊语法,比如NATURALJOIN用来表示自然连接。我们可以把自然连接理解为SQL92中的等值连接。它会帮你自动查询两张连接表中所有相同的字段,然后进行等值连接。

-- SQL92语法
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`
AND e.`manager_id` = d.`manager_id`;

--  SQL99 语法
SELECT employee_id,last_name,department_name
FROM employees e NATURAL JOIN departments d;

USING 连接

当我们进行连接的时候,SQL99还支持使用USING指定数据表里的同名字段进行等值连接。但是只能配合JOIN一起使用

SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
USING (department_id);

SQL函数

单行函数

第07章_单行函数.pdf

多行函数

第08章_聚合函数.pdf

SELECT 查询语句语法结构与执行原理

SELECT 语法结构

#方式1:
SELECT ...,....,...
FROM ...,...,....
WHERE 多表的连接条件
AND 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...


#方式2:
SELECT ...,....,...
FROM ... JOIN ...
ON 多表的连接条件
JOIN ...
ON ...
WHERE 不包含组函数的过滤条件
AND/OR 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...

/*其中:
(1)from:从哪些表中筛选
(2)on:关联多表查询时,去除笛卡尔积
(3)where:从表中筛选的条件
(4)group by:分组依据
(5)having:在统计结果中再次筛选
(6)order by:排序
(7)limit:分页
*/

SELECT语句执行原理

SELECT语句执行顺序:FROM->WHERE->GROUPBY->HAVING->SELECT的字段->DISTINCT->ORDERBY->LIMIT

SELECT 语句在执行这些步骤是,每个步骤都会产生一个虚拟表,然后将这个虚拟表作为输入传入下一个步骤。

SELECT 语句执行原理:

  1. SELECT语句先执行FROM这一步,如果是查询多张表,还会经历一下步骤
    1. 首先通过CROSS JOIN 求出多张表的笛卡尔积,相当于得到虚拟表(virtual table)vt1-1
    2. 然后通过ON进行筛选,在vt1-1基础上根据多表连接条件,生成虚拟表vt1-2
    3. 添加外部行。如果使用左外连接、右外连接或者全连接,就会涉及外部行,也就是在虚拟表vt1-2基础上添加外部行,得到虚拟表vt1-3
    4. 多张表重复以上步骤直到将所有表处理完,由此得到原始数据vt1
  2. SELECT阶段得到的虚拟表vt1作为WHERE阶段的输入,根据字段条件对vt1进行数据过滤,得到虚拟表vt2
  3. vt2作为GROUP阶段输入,对vt2数据根据GROUP条件进行分组得到虚拟表vt3
  4. vt3作为HAVING阶段输入,对vt3数据进行分组过滤得到虚拟表vt4
  5. 根据SELECT 字段,从vt4中提取到要求查询的字段,得到虚拟表vt5-1,然后通过DISTINCT去重,得到虚拟表vt5-2
  6. ORDER BY 对虚拟表去重后的vt5根据指定字段排序,得到虚拟表vt6
  7. LIMIT阶段,对排序后的虚拟表vt6根据要求取出数据,得到最终结果vt7

    子查询

    第09章_子查询.pdf
    子查询指一个查询语句嵌套在另一个查询语句内部的查询。
    SELECT 字段
    FROM 表格
    WHERE 字段 op (SELECT 字段 FROM 另一个表)
    
  • 子查询在主查询之前一次执行完成;
  • 子查询的结果被主查询使用。

    单行子查询

    单行子查询只返回一条结果,主查询使用单行比较符:=、>、<、>=、<=、<>

  • HAVING中的子查询

    • 首先执行子查询
    • 向主查询中的HAVING子句返回结果
  • CASE中的子查询
    • 在CASE表达式中使用单列子查询
  • 子查询中的空值问题
    • 子查询为空时,主查询查询不到任何内容

      多行子查询

      多行子查询也称为集合比较子查询,子查询返回多条结果,主查询使用多行比较符:IN、ANY、ALL、SOME

      相关子查询

      相关子查询的执行依赖外部查询,通常情况是子查询中使用了主查询的表,并进行了条件关联,因为每一次主查询,子查询都要重新计算一次,这样的子查询称为关联子查询
      SELECT 字段
      FROM 表 outter
      WHERE 字段 op (SELECT 字段 FROM 表 WHERE 字段=outer.字段)
      

      相关更新

      使用相关子查询,依据一个表中的数据更新另一个表的数据
      UPDATE table1 alias1
      SET column = (SELECT expression
      FROM table2 alias2
      WHERE alias1.column = alias2.column);
      

      相关删除

      使用相关子查询,依据一个表中的数据删除另一个表中的数据
      DELETE FROM table1 alias1
      WHERE column operator (SELECT expression
      FROM table2 alias2
      WHERE alias1.column = alias2.column);
      

      DDL - 创建和管理数据库与表

      mysql中的数据类型

      第12章_MySQL数据类型精讲.pdf
类型 示例
整数类型 TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER)、BIGINT
浮点类型 FLOAT、DOUBLE
定点数类型 DECIMAL
位类型 BIT
日期时间类型 YEAR、TIME、DATE、DATETIME、TIMESTAMP
文本字符串类型 CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT
枚举类型 ENUM
集合类型 SET
二进制类型 BINARY、VARBINART、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB
JSON类型 JSON对象、JSON数组
空间数据类型 单值:GEOMETRY、POINT、LINESTRING、POLYGON;
集合:MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、
GEOMETRYCOLLECTION

阿里《java开发手册》——数据类型选取

  • 任何字段如果为非负数,必须是UNSIGNED
  • 【强制】小数类型为DECIMAL,禁止使用FLOAT和DOUBLE。
    • 说明:在存储的时候,FLOAT和DOUBLE都存在精度损失的问题,很可能在比较值的时候,得到不正确的结果。如果存储的数据范围超过DECIMAL的范围,建议将数据拆成整数和小数并分开存储。
  • 【强制】如果存储的字符串长度几乎相等,使用CHAR定长字符串类型。
  • 【强制】VARCHAR是可变长字符串,不预先分配存储空间,长度不要超过5000。如果存储长度大于此值,定义字段类型为TEXT,独立出来一张表,用主键来对应,避免影响其它字段索引效率。

    操作数据库

    创建数据库

    ```sql — 创建默认设置数据库 CREATE DATABASE 数据库名;

— 创建数据库指定字符集

CREATE DATABASE 数据库名 CHARACTER SET 字符集;

— 判断数据库是否存在,不存在则创建数据库

CREATE DATABASE IF NOT EXISTS 数据库名;

<a name="zZJ6F"></a>
#### 操作数据库
```sql
-- 查看当前所有数据库
SHOW DATABASES; 

-- 查看当前正在使用的数据看

SELECT DATABASE();

-- 查看指定数据库中所有表

SHOW TABLES FROM 数据库名;

-- 查看数据库的创建信息

SHOW CREATE DATABASE 数据库名;
--或
SHOW CREATE DATABASE 数据库名\G


-- 切换数据库

USE 数据库名

修改数据库

-- 更改数据库字符集

ALTER DATABASE 数据库名 CHARACTER SET 字符集;

删除数据库

-- 删除指定数据库
DROP DATABASE 数据库名;

-- 删除指定数据库

DROP DATABASE IF EXISTS 数据库名

操作表格

创建表格

-- 常规创建表格

CREATE TABLE [IF NOT EXISTS] 表名(
字段1, 数据类型 [约束条件] [默认值],
字段2, 数据类型 [约束条件] [默认值],
字段3, 数据类型 [约束条件] [默认值],
......
[表约束条件]
);

-- 使用AS subquery选项,将新建表和插入数据结合起来

CREATE TABLE 表名(字段) AS 子查询;

修改表格

-- 添加一个列
ALTER TABLE 表名 ADD 【COLUMN】 字段名 字段类型 【FIRST|AFTER 字段名】

-- 修改一个列  可以修改列的数据类型,长度、默认值和位置
ALTER TABLE 表名 MODIFY 【COLUMN】 字段名1 字段类型 【DEFAULT 默认值】【FIRST|AFTER 字段名2】

-- 重名名列
ALTER TABLE 表名 CHANGE 【column】 列名 新列名 新数据类型;

-- 删除一个列

ALTER TABLE 表名 DROP 【column】字段名

-- 重命名表
RENAME TABLE 旧表命 to 新表名

ALTER table 表格 RENAME  TO 新表名;

删除表

-- 删除表:数据和结构都被删除,所有正在运行的事务被提交,所有相关索引被删除
-- DROP TABLE 不能回滚
DROP TABLE [IF EXISTS] 数据表1 [, 数据表2, ..., 数据表n];

-- 清空表:删除表中所有数据,是否表的存储空间
-- TRUNCATE 语句不能回滚
TRUNCATE TABLE 表名
-- DELETE 语句可以回滚
DELETE FROM 表名 

-- TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少,
-- 但 TRUNCATE 无事务且不触发 TRIGGER,有可能造成事故,故不建议在开发代码中使用此语句。

阿里《java开发手册》——mysql字段命名

  • 【强制】表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
    • 正例:aliyun_admin,rdc_config,level3_name
    • 反例:AliyunAdmin,rdcConfig,level_3_name
  • 【强制】禁用保留字,如desc、range、match、delayed等,请参考MySQL官方保留字。
  • 【强制】表必备三字段:id, gmt_create, gmt_modified。
    • 说明:其中id必为主键,类型为BIGINT UNSIGNED、单表时自增、步长为1。gmt_create,gmt_modified的类型均为DATETIME类型,前者现在时表示主动式创建,后者过去分词表示被动式更新
  • 【推荐】表的命名最好是遵循“业务名称_表的作用”。
    • 正例:alipay_task、force_project、trade_config
  • 【推荐】库名与应用名称尽量一致。
  • 【参考】合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检索速度。正例:无符号值可以避免误存负数,且扩大了表示范围。

    MYSQL8.0新特性——DDL操作原子化

    在MySQL 8.0版本中,InnoDB表的DDL支持事务完整性,即DDL操作要么成功要么回滚。DDL操作回滚日志写入到data dictionary数据字典表mysql.innodb_ddl_log(该表是隐藏的表,通过show tables无法看到)中,用于回滚操作。通过设置参数,可将DDL操作日志打印输出到MySQL错误日志中。

    DML - 增删改

    增加数据——INSERT

    ```sql — 为表中所有字段按默认顺序插入数据 INSERT INTO 表名 VALUES (value1,value2,….);

— 为表中指定字段插入数据 INSERT INTO 表名(column1 [, column2, …, columnn]) VALUES (value1 [,value2, …, valuen])

— 同时插入多条数据 INSERT INTO 表名 VALUES (value1 [,value2, …, valuen]), (value1 [,value2, …, valuen]), ……(value1 [,value2, …, valuen]);

INSERT INTO 表名(column1 [, column2, …, columnn]) VALUES (value1 [,value2, …, valuen]), (value1 [,value2, …, valuen]), ……(value1 [,value2, …, valuen]);

— 一个同时插入多行记录的INSERT语句等同于多个单行插入的INSERT语句, — 但是多行的INSERT语句在处理过程中 效率更高 。

— 将查询结果插入到表中:在 INSERT 语句中加入子查询、不必写values子句、子查询中的值列表应与 INSERT 子句中的列名对应 INSERT INTO 目标表名 (tar_column1 [, tar_column2, …, tar_columnn]) SELECT (src_column1 [, src_column2, …, src_columnn]) FROM 源表名 [WHERE condition]

<a name="zW5xj"></a>
### 更新数据——UPDATE
```sql
-- 基本语法
UPDATE table_name
SET column1=value1, column2=value2, ... , column=valuen
[WHERE condition]

删除数据——DELETE

-- 清空表:删除表中所有数据,是否表的存储空间
-- TRUNCATE 语句不能回滚
TRUNCATE TABLE 表名
-- DELETE 语句可以回滚
DELETE FROM 表名 

-- TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少,
-- 但 TRUNCATE 无事务且不触发 TRIGGER,有可能造成事故,故不建议在开发代码中使用此语句。

MYSQL8.0 新特性——计算列

计算列:简单来说就是某一列的值是通过别的列计算得来的。例如,a列值为1、b列值为2,c列不需要手动插入,定义a+b的结果为c的值,那么c就是计算列,是通过别的列计算得来的。
在MySQL 8.0中,CREATE TABLE和ALTER TABLE中都支持增加计算列。

create table tb1(
id int,
a int,
b int,
c int GENERATED ALWAYS AS (a+b) VIRTUAL);

约束

数据完整性(Data Integrity)值数据的精确性(Accuracy)和可靠性(Reliablity)。为保证数据库的完整性,SQL规范约束的方式对数据进行额外的条件限制,从4个方面考虑:

  • 实体完整性(Entity Integrity)
  • 域完整性(Domain Integrity)
  • 引用完整性(Referential Integrity)
  • 用户自定义完整性(User-defined Integrity)

    约束分类

    根据约束作用范围:

  • 列级约束:作用在一个列上,跟在列的定义后面

  • 表级约束:可以作用在多个列上,单独定义

    根据约束作用:

    NOT NULL非空约束,规定某个字段不能为空
  • 默认,所有的类型的值都可以是NULL

  • 非空约束只能出现在表对象的列上,只能某个列单独限定非空,不能组合非空
  • 一个表可以有很多列都分别限定了非空
  • 空字符串’’不等于NULL,0也不等于NULL ```sql — 建表时指定列非空 CREATE TABLE 表名称( 字段名 数据类型, 字段名 数据类型 NOT NULL, 字段名 数据类型 NOT NULL );

— 建表后,修改表某列非空 alter table 表名称 modify 字段名 数据类型 not null

— 删除非空约束 — 去掉not null,相当于修改某个非注解字段,该字段允许为空 alter table 表名称 modify 字段名 数据类型 NULL; 或 alter table 表名称 modify 字段名 数据类型;

<a name="Xz9Zp"></a>
##### UNIQUE唯一约束,规定某个字段在整个表中是唯一的

- 用了限制某个字段值不能重复
- 同一个表可以有多个唯一约束
- 唯一约束可以是一个列值唯一,也可以是多个列组合的值唯一
- 唯一值约束允许列值为空
- 创建唯一约束时不给唯一约束命名,默认和列名相同
- mysql会给唯一约束的列默认创建唯一索引
- 删除唯一约束只能通过删除唯一索引的方式删除
- 删除时需要指定唯一索引名,如果创建唯一索引是没有指定名称,如果是单例,默认和类名相同;如果是组合列,默认和()中排在第一个的列名相同。
```sql
-- 创建表示 指明唯一约束
create table 表名称(
字段名 数据类型,
字段名 数据类型 unique, -- 列级约束
字段名 数据类型 unique key,
字段名 数据类型
);

create table 表名称(
字段名 数据类型,
字段名 数据类型,
字段名 数据类型,
[constraint 约束名] unique key(字段名)  -- 表级约束
);

-- 建表后,指定唯一约束
-- 字段列表中如果是一个字段,表示该列的值唯一。如果是两个或更多个字段,那么复合唯一,即多个字段的组合是唯一的
alter table 表名称 add unique key(字段列表);
alter table 表名称 modify 字段名 字段类型 unique;

-- 查看都有哪些约束
SELECT * FROM information_schema.table_constraints WHERE table_name = '表名'; 
-- 删除唯一约束
ALTER TABLE 表名
DROP INDEX 唯一索引名

PRIMARY KEY主键(非空且唯一)约束
  • 主键约束相当于唯一约束+非空约束的组合,主键约束列不允许重复,也不允许出现空值。
  • 一个表最多只能有一个主键约束,建立主键约束可以在列级别创建,也可以在表级别上创建。
  • 主键约束对应着表中的一列或者多列(复合主键)
  • 如果是多列组合的复合主键约束,那么这些列都不允许为空值,并且组合的值不允许重复。
  • MySQL的主键名总是PRIMARY,就算自己命名了主键约束名也没用。
  • 当创建主键约束时,系统默认会在所在的列或列组合上建立对应的主键索引(能够根据主键查询的,就根据主键查询,效率更高)。如果删除主键约束了,主键约束对应的索引就自动删除了。
  • 需要注意的一点是,不要修改主键字段的值。因为主键是数据记录的唯一标识,如果修改了主键的值,就有可能会破坏数据的完整性。 ```sql — 创建表示指明主键 create table 表名称( 字段名 数据类型 primary key, #列级模式 字段名 数据类型, 字段名 数据类型 ); create table 表名称( 字段名 数据类型, 字段名 数据类型, 字段名 数据类型, [constraint 约束名] primary key(字段名) #表级模式 );

— 建表后新增主键 — 字段列表可以是一个字段,也可以是多个字段,如果是多个字段的话,是复合主键 ALTER TABLE 表名称 ADD PRIMARY KEY(字段列表);

— 删除主键 alter table 表名称 drop primary key;

<a name="ejpvT"></a>
##### 自增 auto_increment

- 一个表最多只能有一个自增长列
- 当需要产生唯一标识符或顺序值时,可设置自增长
- 自增长列约束的列必须是键列(主键列,唯一键列)
- 自增约束的列的数据类型必须是整数类型
- 如果自增列指定了0和null,会在当前最大值的基础上自增;如果自增列手动指定了具体值,直接赋值为具体值。
```sql
-- 创建表时
create table 表名称(
字段名 数据类型 primary key auto_increment,
字段名 数据类型 unique key not null,
字段名 数据类型 unique key,
字段名 数据类型 not null default 默认值,
);
create table 表名称(
字段名 数据类型 default 默认值 ,
字段名 数据类型 unique key auto_increment,
字段名 数据类型 not null default 默认值,,
primary key(字段名)
);

-- 创建表后
alter table 表名称 modify 字段名 数据类型 auto_increment;

-- 删除自增。去掉auto_increment相当于删除
alter table 表名称 modify 字段名 数据类型;

FOREIGN KEY外键约束
  • 限定某个表的某个字段的引用完整性。
  • 从表的外键列,必须引用/参考主表的主键或唯一约束的列。因为被依赖/被参考的值必须是唯一的
  • 在创建外键约束时,如果不给外键约束命名,默认名不是列名,而是自动产生一个外键名(例如student_ibfk_1;),也可以指定外键约束名
  • 创建(CREATE)表时就指定外键约束的话,先创建主表,再创建从表
  • 删表时,先删从表(或先删除外键约束),再删除主表
  • 当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据
  • 在“从表”中指定外键约束,并且一个表可以建立多个外键约束
  • 从表的外键列与主表被参照的列名字可以不相同,但是数据类型必须一样,逻辑意义一致。如果类型不一样,创建子表时,就会出现错误“ERROR 1005 (HY000): Can’t create table’database.tablename’(errno: 150)”。
  • 当创建外键约束时,系统默认会在所在的列上建立对应的普通索引。但是索引名是外键的约束名。(根据外键查询效率很高)
  • 删除外键约束后,必须手动删除对应的索引 ```sql — 创建表时指定外键 create table 主表名称( 字段1 数据类型 primary key, 字段2 数据类型 ); create table 从表名称( 字段1 数据类型 primary key, 字段2 数据类型, [CONSTRAINT <外键约束名称>] FOREIGN KEY(从表的某个字段) references 主表名(被参考字段) );

    (从表的某个字段)的数据类型必须与主表名(被参考字段)的数据类型一致,逻辑意义也一样

    (从表的某个字段)的字段名可以与主表名(被参考字段)的字段名一样,也可以不一样

    — FOREIGN KEY: 在表级指定子表中的列 — REFERENCES: 标示在父表中的列

— 创建表后 ALTER TABLE 从表名 ADD [CONSTRAINT 约束名] FOREIGN KEY (从表的字段) REFERENCES 主表名(被引用字段) [on update xx][on delete xx];

— 删除外键

—(1)第一步先查看约束名和删除外键约束 SELECT * FROM information_schema.table_constraints WHERE table_name = ‘表名称’; ALTER TABLE 从表名 DROP FOREIGN KEY 外键约束名; —(2)第二步查看索引名和删除索引。(注意,只能手动删除) SHOW INDEX FROM 表名称; #查看某个表的索引名 ALTER TABLE 从表名 DROP INDEX 索引名

**外键约束等级**

- Cascade方式:在父表上update/delete记录时,同步update/delete掉子表的匹配记录
- Setnull方式:在父表上update/delete记录时,将子表上匹配记录的列设为null,但是要注意子表的外键列不能为not null
- Noaction方式:如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作
- Restrict方式:同no action,都是立即检查外键约束
- Setdefault方式(在可视化工具SQLyog中可能显示空白):父表有变更时,子表将外键列设置成一个默认的值,但Innodb不能识别
<a name="jvXqe"></a>
##### CHECK检查约束

- 检查某个字段的值是否符号xx要求,一般指的是值的范围
- mysql5.7 不支持,mysql8.0 支持
<a name="T9gjb"></a>
##### DEFAULT默认值约束

- 给某个字段/某列指定默认值,一旦设置默认值,在插入数据时,如果此字段没有显式赋值,则赋值为默认值。
```sql
-- 建表时
create table 表名称(
字段名 数据类型 primary key,
字段名 数据类型 unique key not null,
字段名 数据类型 unique key,
字段名 数据类型 not null default 默认值,
);

-- 建表后修改
alter table 表名称 modify 字段名 数据类型 default 默认值;

alter table 表名称 modify 字段名 数据类型 default 默认值 not null;

-- 删除默认约束,不保留非空约束
alter table 表名称 modify 字段名 数据类型 ;
-- 删除默认值约束,保留非空约束
alter table 表名称 modify 字段名 数据类型 not null;

MYSQL 8.0新特性 —— 自增变量持久化

在MySQL 8.0之前,自增主键AUTO_INCREMENT的值如果大于max(primary key)+1,在MySQL重启后,会重置AUTO_INCREMENT=max(primary key)+1,这种现象在某些情况下会导致业务主键冲突或者其他难以发现的问题。下面通过案例来对比不同的版本中自增变量是否持久化。

视图

第14章_视图.pdf

存储过程与函数

第15章_存储过程与函数.pdf

存储过程

-- 创建存储过程

CREATE PROCEDURE 存储过程名(IN|OUT|INOUT 参数名 参数类型,...)
[characteristics ...]
BEGIN
存储过程体
END

--1 IN:表示当前参数为输入参数;存储过程只是读取这个参数的值,如果没有定义参数种类,默认是IN,表示输入参数。
--2 OUT:表示当前参数为输出参数;执行完之后,调用这个存储过程的客户端或程序就可以读取这个参数返回的值。
--3 INOU:当前参数既可以作为输入参数,也可以作为输出参数
--4 参数类型可以是MYSQL中任意类型
--5 characteristics 表示创建存储过程时指定的对存储过程的约束条件,取值如下
/*
    LANGUAGE SQL
    | [NOT] DETERMINISTIC
    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }
    | COMMENT 'string'

    字段说明:

    ① LANGUAGE SQL:说明存储过程执行体是由SQL语句组成的,当前系统支持的语言为SQL。
    ② [NOT] DETERMINISTIC:指明存储过程执行的结果是否确定。DETERMINISTIC表示结果确定的。
                          每次执行存储过程时,相同的输入会得到相同的输出。NOT DETERMINISTIC相反。默认为NOT DETERMINISTIC。

    ③ { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }:表示子程序是有SQL语句的限制。

          CONTAINS SQL表示当前存储过程的子程序包含SQL语句,但是并不包含读写数据的SQL语句;
          NO SQL表示当前存储过程的子程序中不包含任何SQL语句;
          READS SQL DATA表示当前存储过程的子程序中包含读数据的SQL语句;
          MODIFIES SQL DATA表示当前存储过程的子程序中包含写数据的SQL语句。
          默认情况下,系统会指定为CONTAINS SQL

     ④ SQL SECURITY {DEFINER|INVOKER}:执行当前储存过程的权限,即指明那些用户能够执行当前存储过程。

          DEFINER 表示只有当前存储过程的创建者或者定义者才能执行当前存储过程;
          INVOKER 表示拥有当前存储过程的访问权限的用户能够执行当前存储过程。
          如果没有设置相关的值,则MySQL默认指定值为DEFINER。

     ⑤ COMMENT 'string' :注释信息,可以用来描述存储过程。
*/

--6 存储过程体中可以有多条SQK语句,如果仅仅一条SQL语句,则可以省略BEGIN和END。
/*
          ① BEGIN...END:BEGIN...END 中间包含了多个语句,每个语句都以(;)号为结束符。
          ② DECLARE:DECLARE 用来声明变量,使用的位置在于 BEGIN...END 语句中间,而且需要在其他语句使用之前进行变量的声明。
          ③ SET:赋值语句,用于对变量进行赋值。
          ④ SELECT... INTO:把从数据表中查询的结果存放到变量中,也就是为变量赋值。

*/

--7 设置结束标记:DELIMITER 新的结束标记
--        因为MySQL默认的语句结束符号为分号‘;’。
--    为了避免与存储过程中SQL语句结束符相冲突,需要使用DELIMITER改变存储过程的结束符。


-----示例-----

DELIMITER $

CREATE PROCEDURE 存储过程名(IN|OUT|INOUT 参数名 参数类型,...)
[characteristics ...]
BEGIN
sql语句1;
sql语句2;
END $
-- 调用存储过程
CALL 存储过程名(实参列表);

-- 调用 in 模式的参数
CALL sp1('值');

-- 调用 out 模式参数

SET @name;
CALL sp1(@name);
SELECT @name;

-- 调用 inout 模式参数
SET @name=值;
CALL sp1(@name);
SELECT @name;

存储函数


-- 创建存储函数
CREATE FUNCTION 函数名(参数名 参数类型,...)
RETURNS 返回值类型
[characteristics ...]
BEGIN
函数体 #函数体中肯定有 RETURN 语句
END

-- 参数说明------------
/*

1、参数列表:指定参数为IN、OUT或INOUT只对PROCEDURE是合法的,FUNCTION中总是默认为IN参数。
2、RETURNS type 语句表示函数返回数据的类型;
      RETURNS子句只能对FUNCTION做指定,对函数而言这是 强制 的。
      它用来指定函数的返回类型,而且函数体必须包含一个 RETURN value 语句。
3、characteristic 创建函数时指定的对函数的约束。取值与创建存储过程时相同。
4、函数体也可以用BEGIN...END来表示SQL代码的开始和结束。
   如果函数体只有一条语句,也可以省略BEGIN...END。
*/

-- 调用存储函数
SELECT 函数名(实参列表);

存储过程与存储函数的查看、修改、删除

-- 使用SHOW CREATE语句查看存储过程和函数的创建信息

SHOW CREATE {PROCEDURE | FUNCTION} 存储过程名或函数名

--  使用SHOW STATUS语句查看存储过程和函数的状态信息

SHOW {PROCEDURE | FUNCTION} STATUS [LIKE 'pattern']

-- 从information_schema.Routines表中查看存储过程和函数的信息
SELECT * FROM information_schema.Routines
WHERE ROUTINE_NAME='存储过程或函数的名' [AND ROUTINE_TYPE = {'PROCEDURE|FUNCTION'}]
-- 修改存储过程、函数,不影响存储过程、函数功能,只是修改相关特性
ALTER {PROCEDURE | FUNCTION} 存储过程或函数的名 [characteristic ...]

-- characteristic指定存储过程或函数的特性,其取值信息与创建过程的取值信息略有不同
/*
      { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
      | SQL SECURITY { DEFINER | INVOKER }
      | COMMENT 'string

     ------字段信息------

      CONTAINS SQL ,表示子程序包含SQL语句,但不包含读或写数据的语句。
      NO SQL ,表示子程序中不包含SQL语句。
      READS SQL DATA ,表示子程序中包含读数据的语句。
      MODIFIES SQL DATA ,表示子程序中包含写数据的语句。
      SQL SECURITY { DEFINER | INVOKER } ,指明谁有权限来执行。
            DEFINER ,表示只有定义者自己才能够执行。
            INVOKER ,表示调用者可以执行。
      COMMENT 'string' ,表示注释信息。
*/
-- 删除存储过程、函数
DROP {PROCEDURE | FUNCTION} [IF EXISTS] 存储过程或函数的名

变量、流程控制与游标

第16章_变量、流程控制与游标.pdf

变量

mysql数据库在存储过程和函数中,可以使用变量来存储查询或计算的中间结果数据,或输出最终的结果数据。变量分为系统变量和用户自定义变量。

系统变量

-- 查看所有全局变量
SHOW GLOBAL VARIABLES;

-- 查看所有会话变量
SHOW SESSION VARIABLES;
SHOW VARIABLES;

-- 查看满足条件的部分系统变量。
SHOW GLOBAL VARIABLES LIKE '%标识符%';

-- 查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%标识符%';


-- 查看指定的系统变量的值
SELECT @@global.变量名;

-- 查看指定的会话变量的值
SELECT @@session.变量名;
SELECT @@变量名
-- 方式1:修改MySQL 配置文件 ,继而修改MySQL系统变量的值(该方法需要重启MySQL服务)
-- 方式2 使用set 命令重新设置系统变量的值

--为某个系统变量赋值
--方式1:
SET @@global.变量名=变量值;
--方式2:
SET GLOBAL 变量名=变量值;


--为某个会话变量赋值
--方式1:
SET @@session.变量名=变量值;
--方式2:
SET SESSION 变量名=变量值

用户自定义变量

用户变量是用户自己定义的,作为MySQL编码规范,MySQL中的用户变量以一个“@”开头。根据作用
范围不同,又分为会话用户变量和局部变量。

  • 会话用户变量:作用域和会话变量一样,只对当前连接会话有效。
  • 局部变量:只在BEGIN和END语句块中有效。局部变量只能在存储过程和函数中使用。 ```sql — 变量定义 — 方式1:“=”或“:=” SET @用户变量 = 值; SET @用户变量 := 值;

— 方式2:“:=” 或 INTO关键字 SELECT @用户变量 := 表达式 [FROM 等子句]; SELECT 表达式 INTO @用户变量 [FROM 等子句];

— 查看用户变量

SELECT @用户变量;

```sql
/*
定义:可以使用 DECLARE 语句定义一个局部变量
作用域:仅仅在定义它的 BEGIN ... END 中有效
位置:只能放在 BEGIN ... END 中,而且只能放在第一句
*/

BEGIN
-- 声明局部变量
DECLARE 变量名1 变量数据类型 [DEFAULT 变量默认值];
DECLARE 变量名2,变量名3,... 变量数据类型 [DEFAULT 变量默认值];

--为局部变量赋值
SET 变量名1 = 值;
SELECT 值 INTO 变量名2 [FROM 子句];

--查看局部变量的值
SELECT 变量1,变量2,变量3;

END

定义条件

定义条件就是给MySQL中的错误码命名,这有助于存储的程序代码更清晰。它将一个错误名字和指定的错误条件关联起来。这个名字可以随后被用在定义处理程序的DECLARE HANDLER语句中。

-- 定义条件
DECLARE 错误名称 CONDITION FOR 错误码(或错误条件)
/*
    MySQL_error_code 和 sqlstate_value 都可以表示MySQL的错误。
        MySQL_error_code是数值类型错误代码。
        sqlstate_value是长度为5的字符串类型错误代码。

*/
-- 定义处理方式
DECLARE 处理方式 HANDLER FOR 错误类型 处理语句

/*
处理方式:处理方式有3个取值:CONTINUE、EXIT、UNDO。
      CONTINUE :表示遇到错误不处理,继续执行。
      EXIT :表示遇到错误马上退出。
      UNDO :表示遇到错误后撤回之前的操作。MySQL中暂时不支持这样的操作。

错误类型(即条件)可以有如下取值:
      SQLSTATE '字符串错误码' :表示长度为5的sqlstate_value类型的错误代码;
      MySQL_error_code :匹配数值类型错误代码;  
      错误名称 :表示DECLARE ... CONDITION定义的错误条件名称。
      SQLWARNING :匹配所有以01开头的SQLSTATE错误代码;
      NOT FOUND :匹配所有以02开头的SQLSTATE错误代码;
      SQLEXCEPTION :匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码;

处理语句:如果出现上述条件之一,则采用对应的处理方式,并执行指定的处理语句。语句可以是
像“ SET 变量 = 值 ”这样的简单语句,也可以是使用 BEGIN ... END 编写的复合语句。
*/

-- 定义处理程序的几种方式,
-- 方法1:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info = 'NO_SUCH_TABLE';

-- 方法2:捕获mysql_error_value
DECLARE CONTINUE HANDLER FOR 1146 SET @info = 'NO_SUCH_TABLE';

-- 方法3:先定义条件,再调用
DECLARE no_such_table CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info = 'NO_SUCH_TABLE';

-- 方法4:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info = 'ERROR';

-- 方法5:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info = 'NO_SUCH_TABLE';

-- 方法6:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info = 'ERROR

流程控制

-- if语法:
-- 特点:① 不同的表达式对应不同的操作 ② 使用在begin end中
IF 表达式1 THEN 操作1
[ELSEIF 表达式2 THEN 操作2]......
[ELSE 操作N]
END IF


-- case语法:
-- 情况一:类似于switch
CASE 表达式
WHEN 值1 THEN 结果1或语句1(如果是语句,需要加分号)
WHEN 值2 THEN 结果2或语句2(如果是语句,需要加分号)
...
ELSE 结果n或语句n(如果是语句,需要加分号)
END [case](如果是放在begin end中需要加上case,如果放在select后面不需要)

-- 情况二:类似于多重if
CASE
WHEN 条件1 THEN 结果1或语句1(如果是语句,需要加分号)
WHEN 条件2 THEN 结果2或语句2(如果是语句,需要加分号)
...
ELSE 结果n或语句n(如果是语句,需要加分号)
END [case](如果是放在begin end中需要加上case,如果放在select后面不需要)
--1 loop语法  LOOP内的语句一直重复执行直到循环被退出(使用LEAVE子句),跳出循环过程。
-- 类似java  for 语句
[loop_label:] LOOP
循环执行的语句 
END LOOP [loop_label]  -- loop_label表示LOOP语句的标注名称,该参数可以省略


--2 while语法  WHILE语句创建一个带条件判断的循环过程。
-- WHILE在执行语句执行时,先对指定的表达式进行判断,如果为真,就执行循环内的语句,否则退出循环
-- 类似java while语句
[while_label:] WHILE 循环条件 DO
循环体
END WHILE [while_label];

--3 REPEAT 语法
/*
REPEAT语句创建一个带条件判断的循环过程。
与WHILE循环不同的是,REPEAT 循环首先会执行一次循环,然后在 UNTIL 中进行表达式的判断,如果满足条件就退出,即 END REPEAT;
如果条件不满足,则会就继续执行循环,直到满足退出条件为止。
*/
-- 类似java  do..while 语句
[repeat_label:] REPEAT
循环体的语句
UNTIL 结束循环的条件表达式
END REPEAT [repeat_label]
-- 跳出语句 LEAVE   
-- label参数表示循环的标志。LEAVE和BEGIN ... END或循环一起被使用。
类似java  break
LEAVE 标记名


-- ITERATE
/*
ITERATE语句:只能用在循环语句(LOOP、REPEAT和WHILE语句)内,表示重新开始循环,将执行顺序转到语句段开头处。
*/

-- 类似java continue
ITERATE label

游标

游标,提供了一种灵活的操作方式,让我们能够对结果集中的每一条记录进行定位,并对指向的记录中的数据进行操作的数据结构。游标让SQL这种面向集合的语言有了面向过程开发的能力。

在SQL中,游标是一种临时的数据库对象,可以指向存储在数据库表中的数据行指针。这里游标充当了指针的作用,我们可以通过操作游标来对数据行进行操作。MySQL中游标可以在存储过程和函数中使用。

游标的使用

游标必须在声明处理程序之前被声明,并且变量和条件还必须在声明游标或处理程序之前被声明。

  1. 声明游标 ```sql — 声明游标。适用于 MySQL,SQL Server,DB2 和 MariaDB。 — 要使用 SELECT 语句来获取数据结果集,而此时还没有开始遍历数据, — 这里 select_statement 代表的是SELECT 语句,返回一个用于创建游标的结果集。 DECLARE cursor_name CURSOR FOR select_statement;

— Oracle 或者 PostgreSQL语法 DECLARE cursor_name CURSOR IS select_statement


2. ** 打开游标**
```sql
-- 打开游标
-- 打开游标的时候 SELECT 语句的查询结果集就会送到游标工作区,为后面游标的 逐条读取 结果集中的记录做准备。
OPEN cursor_name
  1. 使用游标 ```sql — 使用游标 FETCH cursor_name INTO var_name [, var_name] …

/*这句的作用是使用 cursor_name 这个游标来读取当前行,并且将数据保存到 var_name 这个变量中,游标指针指到下一行。 如果游标读取的数据行有多个列名,则在 INTO 关键字后面赋值给多个变量名即可。 注意:var_name必须在声明游标之前就定义好

游标的查询结果集中的字段数,必须跟 INTO 后面的变量数一致,否则,在存储过程执行的时候,MySQL 会提示错误。 */


4. ** 关闭游标**
```sql
-- 关闭游标
CLOSE cursor_name

MYSQL8.0新特性 —— 全局变量持久化

在MySQL数据库中,全局变量可以通过SET GLOBAL语句来设置。

-- 例如,设置服务器语句超时的限制,可以通过设置系统变量max_execution_time来实现:
SET GLOBAL MAX_EXECUTION_TIME=2000

使用SET GLOBAL语句设置的变量值只会临时生效。数据库重启后,服务器又会从MySQL配置文件中读取
变量的默认值。MySQL 8.0版本新增了SETPERSIST命令,MySQL会将该命令的配置保存到数据目录下的mysqld-auto.cnf文件中,下次启动时会读取该文件,用其中的配置来覆盖默认的配置文件

-- 设置服务器的最大连接数为1000:
SET PERSIST global max_connections = 1000;

触发器

第17章_触发器.pdf
触发器是由事件来触发某个操作,这些事件包括INSERT、UPDATE、DELETE事件。
所谓事件就是指用户的动作或者触发某项行为。如果定义了触发程序,当数据库执行这些语句时候,就相当于事件发生了,就会自动激发触发器执行相应的操作。

创建触发器

-- 创建触发器
CREATE TRIGGER 触发器名称
{BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON 表名
FOR EACH ROW
触发器执行的语句块;

/*
表名 :表示触发器监控的对象。
BEFORE|AFTER :表示触发的时间。BEFORE 表示在事件之前触发;AFTER 表示在事件之后触发。
INSERT|UPDATE|DELETE :表示触发的事件。
    INSERT 表示插入记录时触发;
    UPDATE 表示更新记录时触发;
    DELETE 表示删除记录时触发。
触发器执行的语句块 :可以是单条SQL语句,也可以是由BEGIN...END结构组成的复合语句块。
*/

查看、删除触发器

-- 查看当前数据库的所有触发器的定以
SHOW TRIGGERS\G

-- 查看当前数据库中某个触发器的定义

SHOW CREATE TRIGGER 触发器名;

-- 从系统库information_schema的TRIGGERS表中查询“salary_check_trigger”触发器的信息。
SELECT * FROM information_schema.TRIGGERS;
-- 删除触发器
DROP TRIGGER IF EXISTS 触发器名称;

MYSQL8.0新特性

第18章_MySQL8其它新特性.pdf

  • 窗口函数
  • 公用表表达式