MySQL基础(二)

目录

约束

概述

外键约束

添加外键

删除/更新行为

多表查询

多表关系

一对多(多对一)

多对多

一对一

多表查询概述

连接查询

内连接

外连接

左外连接

右外连接

自连接

联合查询

子查询

标量子查询

列子查询

行子查询

表子查询

事务

概述

事务操作

第一种操作(修改事务的提交方式)

第二种操作(手动开启事务)

事务的四大特性

并发事务问题

事务隔离级别


约束

概述

约束是作用于表中字段上的规则,用于限制存储在表中的数据(可以在创建、修改表的时候添加约束)

目的:保证数据库中数据的正确、有效和完整

自动增长关键字:auto_increment

检查约束:check(约束条件)

默认约束:defsult '默认值'

外键约束

外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性(主表/父表不能随意更改,因为有副表/子表关联关系)

添加外键

sql 复制代码
CREAT TABLE 表名{
    字段名 数据类型,
    ......
    [CONSTRAINT] [外键名称] FOREIGN KEY(外键字段名) REFERRENCES 主表(主列表名)
};

此方法在创建表时添加外键

外键名称:fk_字段名 (字段名是副表的)

sql 复制代码
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERRENCES 主表(主列表名);

此方法向已经创建的表中添加外键

外键名称:fk_表名_字段名 (表名字段名都是副表的)

主列表名就是主表被关联的字段名

删除/更新行为

语法:

sql 复制代码
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERRENCES 主表(主列表名) ON UPDATE CASCADE ON DELETE CASCADE;

添加外键语法+on update 更新时行为 on delete 删除时行为

多表查询

多表关系

由于业务之间相互关联,所以各个表之间也存在着各种联系:

1、一对多(多对一)

2、多对多

3、一对一

一对多(多对一)

案例:一个部门对应多个员工,一个员工对应一个部门

实现:在多的一方建立外键,指向一的一方的主键(多作为子表,一作为父表)

多对多

案例:一个学生可以选修多门课程,一门课程可以供多个学生选择

实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

一对一

多用于单标拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率

实现:在任意一 方加入外键,关联另一方的主键,并且设置外键为唯一的(UNIQUE),用以保证一对一关系

多表查询概述

指从多张表中查询数据,多表查询时要消除无效的笛卡尔积

连接查询

连接关键字:JOIN

条件关键字:ON(如果没有条件,则结果是所有笛卡尔积/排列组合的所有情况)

内连接

  • 隐式内连接

    sql 复制代码
    SELECT 字段列表 FROM 表1,表2 WHERE 条件...;
  • 显式内连接

    sql 复制代码
    SEKSECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件...;

外连接

左外连接
sql 复制代码
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件...;

查询表1的所有数据包含表1与表2交集部分的数据。

右外连接
sql 复制代码
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件...;

查询表2所有的数据包含表1与表2交集部分的数据

自连接

sql 复制代码
​​​​​​​SELECT 字段列表 FROM 表A 别名A, 表A 别名B ON 条件...;
  • 自连接查询,可以是内连接查询,也可以是外连接查询 (自连接可以搭配内连接和外连接)
  • 自连接的过程必须起别名,同样的表别名不一样,以达到自连接的效果(一张表起不同别名就相当于两张表)

联合查询

sql 复制代码
SELECT 字段列表 FROM 表A ...
UNION[ALL]
SELECT 字段列表 FROM 表B...;

效果:将第一次查询和第二次查询的结果直接拼接合并

  • union all:直接将结果合并
  • union:将结果和并后去重

对于联合查询的多张表的列数(字段数)、字段类型必须保持一致

子查询

SQL语句中嵌套SELECT语句,又称为嵌套查询,又称子查询。

sql 复制代码
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
  • 外部语句可以是增删改查中的任何一个
  • 子查询位置可以在:where之后,from之后,select之后

标量子查询

子查询返回的结果是单个值(数字、字符串、日期等)

常用操作符:= <> > >= <

列子查询

子查询返回结果是一列(可以是多行)(一列就是一个字段)

常用操作符:in, not in, any, some, all

行子查询

子查询返回的结果是一行(可以是多列)

常用操作符:=、<>、in、not in

如果是多列,在判断比较时可以使用括号进行多个值比较:(字段1,字段2) = (返回一行多列的子查询),表示字段1、2的值分别与子查询返回的列一一对应相等

表子查询

子查询返回的结果是多行多列

常用操作符:in(由于是多行多列,结果有多个,所以不能直接使用=,使用in表示满足其中一个即可)

事务

概述

事务是一组操作集合,它是一个不可分割的工作单位,事务会把所有的操作作为一起向系统提交或撤销操作请求。这些操作要么同时成功,有么同时失败。

形象解释:银行转账是一个事务,a转给b1000元,先将a的钱减少1000,再将b的钱增加1000。如果a的钱减少1000后遇到异常,b的钱无法增加1000,则会回滚,a的钱恢复原样,a和b的钱都和原来一样。即a的钱减少和b的钱增加要么同时成功要么同时失败。

事务操作

MYSQL中每一个SQL语句都是一个事务,事务是默认自动提交的

如果事务执行成功执行commit指令,如果执行失败执行rollback指令

第一种操作(修改事务的提交方式)

  • 查看/设置事务的提交方式

    sql 复制代码
    SELECT @@autoxommit;
    SET @@attocommit = 0;
  • 提交事务

    sql 复制代码
    COMMIT;
  • 回滚事务

    sql 复制代码
    ROLLBACK
  • 0表示手动提交,1表示自动提交
  • select查看事务提交方式
  • set设置事务提交方式
  • 提交到数据库后,数据库的数据才会变更,否则只是临时修改
  • 事务操作遇到异常时,执行rollback回滚保证数据库中数据的正确和完整性

第二种操作(手动开启事务)

  • 开启事务
sql 复制代码
START TRANSCTION 或 BEGIN;
  • 提交事务

    sql 复制代码
    COMMIT;
  • 回滚事务

    sql 复制代码
    ROLLBACK;

事务的四大特性

  • 原子性:事务是不可分割的最小操作单元,要么全部成功,要么全部失败
  • 一致性:事务完成时,必须使所有的数据都保持一致状态
  • 隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
  • 持久性:事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

并发事务问题

1、脏读:一个事务读到另一个事务还没有提交的数据

A事务将id为1的数据进行更新但没有提交,而B事务读取到了A事务更新后但没提交的数据

2.不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读

事务B将id为1的数据进行更新并提交,导致事务A第一步和第三步都查询id为1的数据但查询到的内容不一样

3、幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了"幻影"

A事务先第一步查询id为1的数据发现不存在,此时B事务向数据库中插入id为1的数据并提交,然后事务A向数据库插入id为1的数据发现已存在(id为主键不可重复,所以事务A第二步插入会报错),由于默认隔离级别(Repeatable Read已经解决不可重复读问题),A事务第三步再次查询id为1的数据和第一步查询结果一样都是不存在(如果此时存在则是不可重复读问题)。

事务隔离级别

从上至下,事务隔离级别和安全性越来越高,但是性能越来越差

Serializable(串行化):并发操作时,只允许一次一个事物操作,A事务操作时B事务等待,只有当A事务提交完成后B事务才能开始操作,以此解决脏读问题

查看事务的隔离级别

sql 复制代码
SELECT @@TRANSACTION_ISOLATION;

设置事务的隔离级别

sql 复制代码
SET[SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL{READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE};
相关推荐
清水白石0081 小时前
从一个“支付状态不一致“的bug,看大型分布式系统的“隐藏杀机“
java·数据库·bug
Python私教5 小时前
model中能定义字段声明不存储到数据库吗
数据库·oracle
mqiqe8 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
工业甲酰苯胺8 小时前
MySQL 主从复制之多线程复制
android·mysql·adb
BestandW1shEs8 小时前
谈谈Mysql的常见基础问题
数据库·mysql
重生之Java开发工程师8 小时前
MySQL中的CAST类型转换函数
数据库·sql·mysql
教练、我想打篮球8 小时前
66 mysql 的 表自增长锁
数据库·mysql
Ljw...8 小时前
表的操作(MySQL)
数据库·mysql·表的操作
哥谭居民00018 小时前
MySQL的权限管理机制--授权表
数据库