MySQL

一种关系型数据库,以表的结构存储数据

MySQL体系结构

QQ_1734499713309

SQL语句

  1. DDL-数据定义语言

    1
    2
    3
    4
    5
    show databases; 查询所有数据库
    select database(); 查询当前数据库
    create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则];创建
    drop database[if exists] 数据库名; 删除
    use 数据库名; 使用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    -- 创建数据库
    CREATE DATABASE my_database;

    -- 使用数据库
    USE my_database;

    -- 创建数据表
    CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(50) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
  2. DML-数据操作语言

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    -- 普通用法
    INSERT INTO `student`(`name`) VALUES ('zsr');

    -- 插入多条数据,字符串和日期型数据包含在引号中
    INSERT INTO `student`(`name`,`pwd`,`sex`) VALUES ('zsr','200024','男'),('gcc','000421','女');

    -- 省略字段 插入的字段要和数据库中的一一对应
    INSERT INTO `student` VALUES (5,'Bareth','123456','男','2000-02-04','武汉','1412@qq.com',1);

    -- 修改学员名字,指定条件
    UPDATE `student` SET `name`='zsr204' WHERE id=1;

    -- 不指定条件的情况,会改动所有表
    UPDATE `student` SET `name`='zsr204';

    -- 修改多个属性
    UPDATE `student` SET `name`='zsr',`address`='湖北' WHERE id=1;

    -- 通过多个条件定位数据
    UPDATE `student` SET `name`='zsr204' WHERE `name`='zsr' AND `pwd`='200024';

    -- 删除数据(避免这样写,会全部删除)
    DELETE FROM `student`;

    -- 删除指定数据
    DELETE FROM `student` WHERE id=1;

  3. DQL-数据查询语言

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT [ALL | DISTINCT]
    {* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
    FROM table_name [as table_alias]
    [left | right | inner join table_name2] -- 联合查询
    [WHERE ...] -- 指定结果需满足的条件
    [GROUP BY ...] -- 指定结果按照哪几个字段来分组
    [HAVING] -- 过滤分组的记录必须满足的次要条件
    [ORDER BY ...] -- 指定查询记录按一个或多个条件排序
    [LIMIT {[offset,]row_count | row_countOFFSET offset}]; -- 指定查询的记录从哪条至哪条

    QQ_1734478327298
  4. DCL-数据控制语言

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    -- 创建用户
    CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
    -- 授予权限
    GRANT privileges ON database.table TO 'username'@'host';
    SELECT:查询数据的权限。
    INSERT:插入数据的权限。
    UPDATE :更新数据的权限。
    DELETE:删除数据的权限。
    ALL PRIVILEGES:授予所有权限。
    -- 查看用户权限
    SHOW GRANTS FOR 'alice'@'localhost';
    -- 撤销权限
    REVOKE privileges ON database.table FROM 'username'@'host';

查询

  1. 基础查询 DISTINCT去除重复数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    -- 查询全部学生
    SELECT * FROM student;

    -- 查询指定的字段
    SELECT `LoginPwd`,`StudentName` FROM student;

    -- 别名 AS(可以给字段起别名,也可以给表起别名)
    SELECT `StudentNo` AS 学号,`StudentName` AS 学生姓名 FROM student AS 学生表;

    -- 函数 CONCAT(str1,str2,...)
    SELECT CONCAT('姓名',`StudentName`) AS 新名字 FROM student;

    -- 查询系统版本(函数)
    SELECT VERSION();

    -- 用来计算(计算表达式)
    SELECT 100*53-90 AS 计算结果;

    -- 查询自增步长(变量)
    SELECT @@auto_increment_increment;

    -- 查询有哪写同学参加了考试,重复数据要去重
    SELECT DISTINCT `StudentNo` FROM result;

  2. 条件查询 <> != 都是不等于的意思

    1
    select 查询列表 from 表名 where 筛选条件;
  3. 模糊查询

    1
    2
    3
    4
    5
    6
    -- 查询名字含d的同学
    SELECT `StudentNo`,`StudentName` FROM student
    WHERE `StudentName` LIKE '%d%';
    -- 查询名字倒数第二个为d的同学
    SELECT `StudentNo`,`StudentName` FROM student
    WHERE `StudentName` LIKE '%d_';
  4. 分组查询

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    select 分组函数,分组后的字段
    from
    where 筛选条件】
    group by 分组的字段
    having 分组后的筛选】
    order by 排序列表】

    -- 查询不同科目的平均分、最高分、最低分且平均分大于90
    -- 核心:根据不同的课程进行分组
    SELECT SubjectName,AVG(StudentResult),MAX(`StudentResult`),MIN(`StudentResult`)
    FROM result r
    INNER JOIN `subject` s
    on r.SubjectNo=s.SubjectNo
    GROUP BY r.SubjectNo
    HAVING AVG(StudentResult)>90;

  5. 连接查询

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    -- 隐式内连接 内连接查的是两个表的交集
    SELECT 字段列表 FROM1,.2 WHERE 条件...;
    -- 显式内连接
    SELECT字段列表 FROM1[INNER]JOIN2 ON 连接条件...;

    -- 外连接
    -- 左外连接
    SELECT 字段列表 FROM1 LEFT[OUTER]JOIN2 ON 条件
    -- 相当于查询表1(左表)的所有数据 包含 表1和表2交集部分的数据
    -- 右外连接
    SELECT 字段列表 FROM1 RIGHT[OUTER]JOIN2 ON 条件
    -- 相当于查询表2(右表)的所有数据 包含 表1和表2交集部分的数据

    -- 自连接查询语法
    SELECT字段列表 FROM 表A 别名AJOIN 表A 别名B ON 条件...;
  6. 联合查询

    1
    2
    3
    4
    5
    6
    -- 对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集
    SELECT 字段列表 FROM 表A …
    UNION [ ALL ]
    SELECT 字段列表 FROM 表B …;
    -- 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
    union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重
  7. 子查询

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    -- SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询
    SELECT *FROM t1 WHERE column1=(SELECT column1 FROM t2 );
    -- 子查询外部的语句可以是INSERT/UPDATE/DELETE/SELECT的任何一个
    -- 根据子查询位置,分为:WHERE之后、FROM之后、SELECT之后。

    -- 查询‘课程设计’的所有考试结果(学号,科目编号,成绩)降序排列

    -- 方式一:使用连接查询
    SELECT `StudentNo`,r.`SubjectNo`,`StudentResult`
    FROM result r
    INNER JOIN `subject` s
    on r.StudentNo=s.SubjectNo
    WHERE SubjectName='课程设计'
    ORDER BY StudentResult DESC;
    -- 方式二:使用子查询(由里到外)
    SELECT StudentNo,SubjectNo,StudentResult
    from result
    WHERE SubjectNo=(
    SELECT SubjectNo FROM `subject`
    WHERE SubjectName='课程设计'
    )
  8. 排序和分页

    1
    2
    3
    4
    5
    select 查询列表
    from
    where 筛选条件
    order by 排序列表 asc/desc
    -- asc 升序 desc降序 order by的位置一般放在查询语句的最后(除limit语句之外)

常用函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
-- 数学运算
SELECT ABS(-8); -- 绝对值
SELECT CEIL(5.1); -- 向上取整
SELECT CEILING(5.1); -- 向上取整
SELECT RAND(); -- 返回0~1之间的一个随机数
SELECT SIGN(-10); -- 返回一个数的符号;0返回0;正数返回1;负数返回-1

-- 字符串函数
SELECT CHAR_LENGTH('我喜欢你'); -- 字符串长度
SELECT CONCAT('我','喜欢','你'); -- 拼接字符串
SELECT INSERT('我喜欢',1,1,'超级') -- INSERT(str,pos,len,newstr) 从str的pos位置开始替换为长度为len的newstr
SELECT UPPER('zsr'); -- 转大写
SELECT LOWER('ZSR'); -- 转小写
SELECT INSTR('zsrs','s'); -- 返回第一次出现字串索引的位置
SELECT REPLACE('加油就能胜利','加油','坚持'); -- 替换出现的指定字符串
SELECT SUBSTR('坚持就是胜利',3,6); -- 返回指定的字符串(源字符串,截取位置,截取长度)
SELECT REVERSE('rsz'); -- 反转字符串

-- 时间日期函数
SELECT CURRENT_DATE(); -- 获取当前日期
SELECT CURDATE(); -- 获取当前日期
SELECT now(); -- 获取当前时间
SELECT LOCALTIME(); -- 本地时间
SELECT SYSDATE(); -- 系统时间

SELECT YEAR(NOW());
SELECT MONTH(NOW());
SELECT DAY(NOW());
SELECT HOUR(NOW());
SELECT MINUTE(NOW());
SELECT SECOND(NOW());

-- 系统信息
SELECT SYSTEM_USER();
SELECT USER();
SELECT VERSION();

聚合函数

1
2
3
4
5
6
7
8
9
SELECT COUNT(StudentName) FROM student; 
SELECT COUNT(*) FROM student;
SELECT COUNT(1) FROM student;

SELECT SUM(`StudentResult`) FROM result;
SELECT AVG(`StudentResult`) FROM result;
SELECT MAX(`StudentResult`) FROM result;
SELECT MIN(`StudentResult`) FROM result;

事务

  1. 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  2. 一致性(Consistency) 事务前后数据的完整性必须保持一致。
  3. 隔离性(Isolation) 事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
  4. 持久性(Durability) 事务一旦被提交则不可逆,被持久化到数据库中,接下来即使数据库发生故障也不应该对其有任何影响
  5. 默认MySQL的事务是自动提交的,执行一条DML语句,MySQL会隐式的提交事务

导致的问题

脏读 指一个事务读取了另外一个事务未提交的数据。
不可重复读 在一个事务内读取表中的某一行数据,多次读取结果不同。
虚读(幻读) 是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
读已提交(read-committed)
可重复读(repeatable-read)
串行化(serializable)

可重复读是MySQL默认的隔离级别

操作代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 关闭自动提交
SET autocommit=0;
-- 事务开启
START TRANSACTION -- 标记一个事务的开始,从这个之后的sql都在同一个事务内
-- 成功则提交,失败则回滚
-- 提交:持久化(成功)
COMMIT
-- 回滚:回到原来的样子(失败)
ROLLBACK
-- 事务结束
SET autocommit=1; -- 开启自动提交
-- 其他操作
SAVEPOINT 保存点名; -- 设置一个事务的保存点
ROLLBACK TO SAVEPOINT 保存点名; -- 回滚到保存点
RELEASE SAVEPOINT 保存点名; -- 撤销保存点

索引

  1. 什么是索引: 是帮助MySQL高效获取数据的数据结构
  2. 索引设计原则
    1. 选择性原则:索引列应该具有高选择性,即列中不同值的数量与表中总行数的比例高。这样可以减少索引中的重复值,提高查询效率。
    2. 最左前缀匹配原则:对于组合索引,MySQL会从左到右使用索引中的列。因此,将选择性最高的列放在最左边,可以最大化索引的使用效率。
    3. 索引列的顺序:在组合索引中,列的顺序应该基于查询条件中列的出现顺序和选择性。
    4. 避免冗余索引:如果一个索引包含了另一个索引的所有列,那么后者就是冗余的,应该删除。
    5. 考虑查询模式:根据应用的查询模式设计索引。如果某些查询非常频繁,应该为这些查询创建索引。
    6. 索引维护成本:索引虽然可以提高查询效率,但会增加插入、删除和更新操作的开销。因此,需要权衡索引带来的性能提升和维护成本。
    7. 使用合适的索引类型:根据数据的特性和查询需求选择合适的索引类型。
    8. 监控和优化:定期监控索引的使用情况,移除不常用的索引,优化常用的索引。
    9. 考虑列的数据类型:某些数据类型(如VARCHAR)在创建索引时需要指定前缀长度,这会影响索引的效率。
    10. 避免全表扫描:尽可能设计索引以避免全表扫描,特别是在大数据量的表中。
  3. 使用索引的好处
    1. 提高查询速度
    2. 确保数据的唯一性
    3. 可以加速表和表之间的连接 , 实现表与表之间的参照完整性
    4. 使用分组和排序子句进行数据检索时 , 可以显著减少分组和排序的时间
    5. 全文检索字段进行搜索优化

使用索引的优缺点

  1. 优点
    • 提高数据检索的效率,降低数据库的IO成本
    • 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗
  2. 缺点
    • 占据空间
    • 提高了查询的效率,但降低了更新表的速度
  3. 支持索引的引擎
    • Memory引擎支持hash索引
    • InnoDB使用B+tree索引结构,具有自适应hash功能,hash索引根据B+Tree索引在指定条件下自动构建
  4. 为什么InnoDB使用B+tree
    • 相对于二叉树,层级更少,搜索效率更高
    • 对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致
      页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的
      高度,导致性能降低;
    • 相对Hash索引,B+tree支持范围匹配及排序操作

索引分类

  1. 主键索引

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    唯一的标识,主键不可重复,只有一个列作为主键
    最常见的索引类型,不允许为空值
    确保数据记录的唯一性
    确定特定数据记录在数据库中的位置
    -- 创建表的时候指定主键索引
    CREATE TABLE tableName(
    ......
    PRIMARY INDEX (columeName)
    )

    -- 修改表结构添加主键索引
    ALTER TABLE tableName ADD PRIMARY INDEX (columnName)
  2. 普通索引

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    index 和 key 关键字都可以设置常规索引
    应加在查询找条件的字段
    不宜添加太多常规索引,影响数据的插入,删除和修改操作
    -- 直接创建普通索引
    CREATE INDEX indexName ON tableName (columnName)

    -- 创建表的时候指定普通索引
    CREATE TABLE tableName(
    ......
    INDEX [indexName] (columeName)
    )

    -- 修改表结构添加普通索引
    ALTER TABLE tableName ADD INDEX indexName(columnName)
  3. 唯一索引

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值
    与主键索引的区别:主键索引只能有一个、唯一索引可以有多个
    -- 直接创建唯一索引
    CREATE UNIQUE INDEX indexName ON tableName(columnName)

    -- 创建表的时候指定唯一索引
    CREATE TABLE tableName(
    ......
    UNIQUE INDEX [indexName] (columeName)
    );

    -- 修改表结构添加唯一索引
    ALTER TABLE tableName ADD UNIQUE INDEX [indexName] (columnName)
  4. 全文索引

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    快速定位特定数据(百度搜索就是全文索引)
    在特定的数据库引擎下才有:MyISAM
    只能用于CHAR , VARCHAR , TEXT数据列类型
    适合大型数据集
    -- 增加一个全文索引
    ALTER TABLE `student` ADD FULLTEXT INDEX `StudentName`(`StudentName`);

    -- EXPLAIN 分析sql执行的情况
    EXPLAIN SELECT * FROM student; -- 非全文索引
    EXPLAIN SELECT * FROM student WHERE MATCH(StudentName) AGAINST('d'); -- 全文索引

索引的使用

  1. 使用原则

    • 索引不是越多越好,小数据量的表不需要加索引
    • 不要对经常变动的数据增加索引
    • 索引一般加在经常要查询的列上
  2. 索引的创建

    1
    2
    3
    4
    5
    CREATE TABLE 表名 (
    字段名1 数据类型 [完整性约束条件…],
    字段名2 数据类型 [完整性约束条件…],
    [UNIQUE|FULLTEXT|SPATIAL] INDEX|KEY [索引名] (字段名[(长度)] [ASC |DESC])
    );
  3. 查看索引

    1
    SHOW INDEX FROM table name ;
  4. 创建后添加索引

    1
    2
    3
    4
    5
    6
    7
    -- 方法一:CREATE在已存在的表上创建索引
    CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名
    ON 表名 (字段名[(长度)] [ASC |DESC]) ;

    -- 方法二:ALTER TABLE在已存在的表上创建索引
    ALTER TABLE 表名 ADD [UNIQUE|FULLTEXT|SPATIAL]
    INDEX 索引名 (字段名[(长度)] [ASC |DESC]) ;
  5. 索引的删除

    1
    2
    3
    4
    -- 删除索引
    DROP INDEX 索引名 ON 表名;
    -- 删除主键索引
    ALTER TABLE 表名 DROP PRIMARY KEY;

存储引擎

QQ_1734499976631
  1. 早期MySQL使用MyISAM引擎,5.5后InnoDB是MySQL默认的存储引擎

  2. InnoDB特点

    • DML操作遵循ACID模型,支持事务
    • 行级锁,提高并发访问性能
    • 支持外键FOREIGN KEY 约束,保证数据的完整性和正确性
  3. MyISAM

    • 不支持事务,不支持外键
    • 支持表锁,不支持行锁
    • 访问速度快
  4. Memory

    • 内存存放
    • hash索引
  5. InnoDB根据索引的存储形式,分为以下两种

    QQ_1734501073821
  6. 其他

    QQ_1734500515023

视图

  1. 是一种虚拟存在的表,视图中的数据并不在数据库中实际存在,行和列的数据来自定义视图的查询中使用的表,并且实在使用视图时动态产生的
  2. 视图只保存查询的SQL逻辑,不保存查询结果
  3. 可以一个视图创建另一个视图
  4. 好处
    • 简单:简化用户对数据的理解,简化他们的操作
    • 安全:用户只能查询和修改他们所能见到的数据
    • 数据独立:帮助用户屏蔽真实表结构带来的影响

视图操作

  1. 创建视图

    1
    CREATE [OR REPLACE]VIEW 视图名称((列名列表)】AS SELECT语句[WITH[CASCADED|LOCAL] CHECK OPTION]
  2. 查询视图

    1
    2
    查看创建视图语句:SHOW CREATE VIEW 视图名称
    查看视图数据:SELECT*FROM 视图名称
  3. 修改

    1
    2
    方式一:CREATE [OR REPLACE]VIEW 视图名称(列名列表)】AS SELECT语句[WITH[CASCADED|LOCAL]CHECK OPTION]
    方式二:ALTER VIEW 视图名称((列名列表)AS SELECT语句[WITH[CASCADED|LOCAL]CHECK OPTION]
  4. 删除

    1
    DROP VIEW [IF EXISTS] 视图名称  [,视图名称]...

视图的更新

QQ_1734501671125 ## 存储过程

概述和特点

  1. 事先经过编译并存储在数据库中的一段SQL语句的集合
  2. 数据库SQL语言层面的代码封装和复用
  3. 简化开发人员的工作
  4. 减少数据在数据库和应用程序之间的传输
  5. 特点
    • 封装,复用
    • 可以接受参数,也可以返回数据
    • 减少网络交互,效率提升

使用

  1. 创建

    1
    2
    3
    4
    CREATE PROCEDURE 存储过程名称([.参数列表 ])
    BEGIN
    -- SOL语句
    END
  2. 调用

    1
    call 名称([参数]);
  3. 查看

    1
    2
    SELECT* FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='xx';--查询指定数据库的存储过程及状态信息
    SHOW CREATE PROCEDURE 存储过程名称;--查询某个存储过程的定义
  4. 删除

    1
    drop procedure [if exists] 存储过程的名称;
  5. 命令行

    1
    2
    3
    在命令行中,执行创建存储过程的SQL时,
    需要通过关键字 delimiter 指定SQL语句的结束符。
    用$$结束

变量

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

  2. 查看系统变量

    1
    2
    3
    SHOW [SESSION|GLOBAL] VARIABLES;-- 查看所有系统变量
    SHOW [SESSION |GLOBAL] VARIABLES LIKE '.......';-- 可以通过LKE模糊匹配方式查找变量
    SELECT @@[SESSION|GLOBAL] 系统变量名;-- 查看指定变量的值
  3. 设置系统变量

    1
    2
    SET [SESSION|GLOBAL]系统变量名=
    SET @@[SESSION|GLOBAL]系统变量名=值,
  4. 如果没有指定SESSION/GLOBAL,默认是SESSION会话变量,mysql服务重新启动之后,所设置的全局参数会失效,要想不失效,可以在 /etc/mny.cnf 中配置

  5. 用户定义变量

    • 作用域为当前连接

    • 赋值

      1
      2
      3
      4
      SET @var name =expr [, @var_name = expr] ... ;
      SET @var name :=expr [, @var name := expr]...
      SELECT @var name := expr [, @var name := expr]...
      SELECT 字段名 INTO @var_name FROM 表名
    • 使用

      1
      select @var_name;
    • 用户定义变量无需声明或初始化,没有初始化取到的值为NULL

  6. 局部变量

    • 作用域为begin…end块

    • 访问之前需要用DECLARE声明

    • 参数

      QQ_1734502811637
    • 用法

      1
      2
      3
      4
      CREATE PROCEDURE 存储过程名称([IN/OUT/INQUT 参数名 参数类型 ])
      BEGIN
      -- SQL语句
      END ;

游标

  1. 用来存储查询的结果集的数据类型

  2. 存储过程和函数中可以使用游标对结果集进行循环的处理

  3. 具体使用

    • 声明游标

      1
      DECLARE 游标名称 CURSOR FOR 查询语句
    • 打开游标

      1
      open 游标名称;
    • 获取游标记录

      1
      fetch 游标名称 info 变量[,变量];
    • 关闭游标

      1
      close 游标名称;
      QQ_1734503174402

存储函数

  1. 有返回值的存储过程,存储函数的参数类型只能是IN类型的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE FUNCTION 存储函数名称([参数列表])
    RETURNS type [characteristic ...
    BEGIN
    -- SQL语句
    RETURN ....
    END ;
    characteristic说明:
    DETERMINISTIC:相同的输入参数总是产生相同的结果
    NO SOL:不包含 SQL语句。
    READS SOL DATA:包含读取数据的语句,但不包含写入数据的语句

触发器

定义

数据库对象在执行insert/update/delete之前或之后,触发并执行触发器中定义的SQL语句的集合

保证数据的完整性、日志记录、数据校验

类型

QQ_1734503410657

语法

  1. 创建

    1
    2
    3
    4
    5
    6
    CREATE TRIGGER trigger name
    BEFORE/AFTER INSERT/UPDATE/DELETE
    ON tbl name FOR EACH ROW --行级触发器
    BEGIN
    trigger stmt ;
    END;
  2. 查看

    1
    show triggers;
  3. 删除

    1
    drop triggers [schema_name.] trigger_name; -- 没有指定schema_name就是当前数据库

锁是计算机协调多个进程或线程并发访问某一资源的机制,锁冲突是影响数据库并发访问性能的一个重要因素

分类

  1. 全局锁:锁定数据库中的所有表。

    • 加锁后整个实例就处于只读状态,后续的DML,DDL,已经更新的操作事务语句都会被阻塞
    • 做全库的逻辑备份,获取一致的视图性,保证数据的完整性
    • 特点
      1. 在主库上备份,备份期间都不能执行更新,业务停摆
      2. 在从库上备份,备份期间从库不能执行主库同步过来的二进制日志,主从延迟
  2. 表级锁:每次操作锁住整张表。

    • 发生锁冲突的概率最高,并发度最低

    • 分为表锁,元数据锁,意向锁

      1. 表锁

        • 表共享读锁(read lock):不会阻塞其他客户端读,会阻塞写

        • 表独占写锁(write lock) :只在本地客户端可读可写

        • 语法

          QQ_1734504218984
      2. 元数据锁(MDL)

        • 系统自动控制,无需显式使用,访问任意一张表时会自动加上
        • 维护表元数据的一致性
        • MySQL5.5中引入了MDL
          1. 对一张表进行增删改查时加MDL读锁(共享)
          2. 对表结构进行变更操作时加MDL写锁(排他)
      3. 意向锁

        • 解决InnoDB中行锁和表锁冲突的问题
        • 使得表锁不用检查每行数据是否加锁,使用意向锁减少表锁的检查
        • QQ_1734504607748
  3. 行级锁:每次操作锁住对应的行数据。

    • InnoDB通过对索引上的索引项加锁实现的,没有索引对所有字段加锁升级为表锁
    • 分为行锁,间隙锁,临键锁
    • InnoDB实现了两种类型的行锁
      • 共享锁(s):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁
      • 排他锁(x):允许获取排他锁的事务更新数据,阻止其他事务获得相同的数据集的共享锁和排他锁
    • 间隙锁唯一目的是为了防止其他事务插入间隙,间隙锁可以共存,一个事务采用间隙锁不会阻止另一个事务在同一间隙上采用间隙锁