mysql外键和子查询
外键
外键:foreign key,外面的键(键不在自己表中):如果一张表中有一个字段(非主键)指向另外一张表的主键,那么该字段称之为外键。
增加外键
外键可以在创建表的时候或者创建表之后增加(但是要考虑数据的问题)。
创建表的时候增加外键:在所有的表字段之后,使用foreign key(外键字段)references 外部表(主键字段)
外键要求字段本身是一个索引(普通索引) 如果字段本身没有索引,外键会首先创建一个索引,然后才会创建外键本身
在新增表之后增加外键:修改表结构
alter table 表名 add [constraint 外键名字] foreign key(外键字段)referneces 父表(主键字段);
修改外键 & 删除外键
外键不可修改:只能先删除后新增
删除外键语法
alter table 表名 drop foreign key 外建名,一张表可以有多个外键,但是外键名不能相同 ;
删除一个外键无法从表结构看出来,要去看表创建语句
外键作用
外键默认的作用有两点:一个对父表,一个对字表(外键字段所在的表)
对子表约束: 子表数据进行写操作(增和改)的时候,如果对应的外键字段在父表找不到对应的匹配:那么操作会失败(约束子表数据操作)
对父表约束:父表数据进行写操作(删和改:都必须涉及到主键本身),如果对应的主键在子表中已经被数据所引用,那就不允许操作
外键条件
1、外键要存在:首先必须保证表的存储引擎是innodb(默认的存储引擎):如果不是innodb存储引擎,那么外键可以创建成功,但是没有约束效果
2、外键字段的字段类型(列类型)必须与父表的主键类型完全一致
3、一张表中的外键名字不能重复
4、增加外键的字段(数据已经存在),必须保证数据与父表主键要求对应。
外键约束
所谓外键约束:就是指外键的作用
之前所讲的外键作用:是默认的作用,其实可以通过对外键的需求,进行定制操作
外键约束有三种约束模式:都是针对父表的约束
distric:严格模式(默认):父表不能删除或者更新一个已经被子表数据引用的记录
cascasde:级联模式,父表的操作,对应子表关联的数据也跟着被删除
set null:置空模式,父表的操作之后,子表对应的数据(外键字段)被置空
通常的一个合理的做法(约束模式):删除的时候子表置空,更新的时候子表级联操作
指定模式的语法
foreign key(外键字段)references 父表(主键字段)on delete 模式 on update 模式;
删除置空的前提条件:外键字段允许为空(如果不满足条件,外键无法创建)
外键虽然很强大,能够进行各种约束:但是对于后端语言来讲,外键的约束降低了后端语言对数据的可控性:通常在实际开发中,很少使用外键来处理
联合查询
联合查询:将多次查询(多条select语句),在记录上进行拼接(字段不会增加)
基本语法
多条select语句构成:每一条select语句获取的字段数必须严格一致(但是字段类型无关)
select 语句 1
union [union 选项]
select 语句 2
union选项:与select选项一样有两个
All:保留所有(不管重复)
Distinct:去重(整个重复):默认的
联合查询只要求字段一样,跟数据类型无关,保留的是第一张表的字段
意义
1、联合查询的意义分为两种:查询同一张表但是需求不同。
2、多表查询:多张表的结构是完全一样的,保存的数据(结构)也是一样的
order by 使用
在联合查询中:order by 不能直接使用,需要对查询语句使用括号才行
若要order by生效:必须搭配limit:limit使用限定的最大数即可。
子查询
子查询:sub query,查询是在某个查询结果之上进行的(一条select语句内部包含了另外一条select语句)。
子查询分类
子查询有两种分类方式:按位置分类,按结果分类
按位置分类:子查询(select语句)在外部查询(select 语句)中出现的位置
from子查询:子查询跟在from之后
where子查询:子查询出现在where条件中
exists子查询:子查询出现在exists里面
按结果分类:根据子查询得到的数据进行分类(理论上讲任何一个查询得到的结果都可以理解为二维表)
标量子查询:子查询得到的结果是一行一列
列子查询:子查询得到的结果是一行多列
行子查询:子查询得到的结果是多列一行(多行多列)
上面几个出现的位置都是在where之后
表子查询:子查询得到的结果是多行多列(出现的位置是在from之后)
标量子查询
select * from xxx where id = (select id from xxx)
查询出的结果一行一列,作为另一个查询语句的条件
列子查询
列子查询返回的结果会比较:一行多列,需要使用in 作为条件匹配,其实在mysql中海油一个类似的条件:all,some,any(基本不用TnT)
=any ====== in
any ====== some; any和some是一样的
=all ====== 为全部
这几种写法都可以被in替换,所以基本没啥用
行子查询
行子查询:返回的结果是多行多列(一行多列)
行子查询:需要构造行元素,行元素由多个字段构成
表子查询
表子查询:子查询返回的结果是多行多列的二维表:子查询返回的结果是当做二维表来使用
表查询:from子查询:得到的结果作为from的数据源
exists子查询
exists:是否存在的意思,exists子查询就是用来判断某些条件是否满足(跨表),exists是接在wehre 之后,exists返回的结果只有0和1。
子查询返回的结果是多行多列的二维表:子查询返回的结果是当做二维表来使用
表查询:from子查询:得到的结果作为from的数据源
exists子查询
exists:是否存在的意思,exists子查询就是用来判断某些条件是否满足(跨表),exists是接在wehre 之后,exists返回的结果只有0和1。