目录
约束
概述
约束是作用于表中字段上的规则,用于限制存储在表中的数据(可以在创建、修改表的时候添加约束)
目的:保证数据库中数据的正确、有效和完整
自动增长关键字: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(如果没有条件,则结果是所有笛卡尔积/排列组合的所有情况)
内连接
-
隐式内连接
sqlSELECT 字段列表 FROM 表1,表2 WHERE 条件...;
-
显式内连接
sqlSEKSECT 字段列表 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指令
第一种操作(修改事务的提交方式)
-
查看/设置事务的提交方式
sqlSELECT @@autoxommit; SET @@attocommit = 0;
-
提交事务
sqlCOMMIT;
-
回滚事务
sqlROLLBACK
- 0表示手动提交,1表示自动提交
- select查看事务提交方式
- set设置事务提交方式
- 提交到数据库后,数据库的数据才会变更,否则只是临时修改
- 事务操作遇到异常时,执行rollback回滚保证数据库中数据的正确和完整性
第二种操作(手动开启事务)
- 开启事务
sql
START TRANSCTION 或 BEGIN;
-
提交事务
sqlCOMMIT;
-
回滚事务
sqlROLLBACK;
事务的四大特性
- 原子性:事务是不可分割的最小操作单元,要么全部成功,要么全部失败
- 一致性:事务完成时,必须使所有的数据都保持一致状态
- 隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
- 持久性:事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
并发事务问题
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};