1 外键
- 外键:foreign key,外面的键(键不在自己表中),如果一张表中有一个字段(非主键)指向另外一张表的主键,那么将该字段称为外键。
1.1 增加外键
- 外键可以在创建表的时候或创建表之后增加(但是要考虑数据的问题)。
- 方案一:在创建表的时候增加外键,在所有的表字段之后,使用foreign key(外键字段) references 外部表 (主键字段);
-- 创建班级 CREATE TABLE my_class( id INT PRIMARY KEY AUTO_INCREMENT, c_name ) NOT NULL, room ) ); -- 创建学生表 CREATE TABLE my_student1( id INT PRIMARY KEY AUTO_INCREMENT, NAME ) NOT NULL, c_id INT , CONSTRAINT fk_c_id FOREIGN KEY (c_id) REFERENCES my_class (id) );
- 方案二:在新增表之后,增加外键,所以需要修改表结构。
alter table 表名 add [constraint 外键名字] foreign key (外键字段) references 父表(主键字段);
-- 创建班级 CREATE TABLE my_class( id INT PRIMARY KEY AUTO_INCREMENT, c_name ) NOT NULL, room ) ); -- 创建学生表 CREATE TABLE my_student2( id INT PRIMARY KEY AUTO_INCREMENT, NAME ) NOT NULL, c_id INT ); ALTER TABLE my_student2 ADD CONSTRAINT fk_c_id FOREIGN KEY (c_id) REFERENCES my_class (id);
1.2 修改外键&删除外键
- 外键不可以修改:只能先删除后新增。
alter table 表名 drop foreign key 外键名;--一张表中可以有多个外键,但是名字不能相同
ALTER TABLE my_student2 DROP FOREIGN KEY fk_c_id;
1.3 外键作用
- 外键默认的作用有两点:
- 一个对父表:父表数据进行写操作(删和改,都必须设计到主键本身),如果对应的主键在字表中已经被数据所引用,那么就不允许操作。
- 一个对字表(外键字段所在的表):字表数据进行写操作(增和改)的时候,如果对应的外键字段在父表找不到对应的匹配,操作会失败。
1.4 外键条件
- 外键要存在:首先必须表的存储引擎是innodb。如果不是innodb存储引擎,那么外键可以创建成功,但是没有约束效果。
- 外键字段的字段类型(列类型)必须和父表的主键类型完全一致。
- 一张表中的外键名字不能重复。
- 增加外键的字段(数据已经存在),必须保证数据和父表主键要求对应。
1.5 外键约束
- 外键约束:就是外键的作用。
- 外键约束有三种约束模式:都是针对父表的约束
- district:严格模式(默认的),父表不能删除或更新一个已经被子表数据引用的记录(主键)。
- cascade:级联模式,父表的操作,对应子表关联的数据也随之变化。
- set null:置空模式,父表的操作之后,子表对应的数据(外键)被置空。
- 通常:父表删除的时候,子表置空;更新的时候,子表级联操作。
constraint 外键名字 foreign key (外键字段) references 主表(主键) on delete set null;
constraint 外键名字 foreign key (外键字段) references 主表(主键) on update cascade;
constraint 外键名字 foreign key (外键字段) references 主表(主键) on delete set null on update cascade;
- 删除置空的前提:外键字段为空(如果不满足条件,外键无法创建)。
- 外键虽然很强大,能够进行各种约束,但是对于java来说,外键约束降低了java对数据的可控性。所以,通常情况下,在实际开发中,很少使用外键的级联模式和置空模式。
2 联合查询
- 联合查询:将多次查询语句,在记录上进行拼接。
- 基本语法
多条select语句构成:每一条select语句获取的字段必须严格一致(但是字段类型无关)
select 语句1 union [union 选项] 语句2……; -- union选项:与select选项一样有两个 -- all 保留所有(不管重复) -- distinct 去重(整个重复):默认的
- 示例:联合查询
SELECT * FROM my_class UNION SELECT * FROM my_class;
- 示例:联合查询
SELECT id,c_name,room FROM my_class UNION SELECT id,c_id,NAME FROM my_student2;
- 联合查询的意义
- 查询同一张表,但是需求不同:如查询学生信息,男生身高升序,女生身高降序(面试题)。
- 多表查询:多张表的结构是完全一样的,保存的数据(结构)也是一样的。
- 联合查询Order by使用
- 在联合查询中:order by不能直接使用,需要对查询语句使用括号才行。
(SELECT * FROM my_student2 WHERE sex = '男' ORDER BY height ASC) UNION (SELECT * FROM my_student2 WHERE sex = '女' ORDER BY height DESC);
- 如果想order by生效:必须搭配limit,limit使用限定的最大数即可。
() UNION ();
3 子查询
- 子查询:查询是在某个查询结果之上进行的(一条select语句内部包含了另外一条select语句)。
- 子查询分类方式:
- 按位置分类:子查询(select语句)在外部查询(select语句)中出现的位置。
- From子查询:子查询在From之后
- where子查询:子查询出现在where条件中
- exists子查询:子查询出现在exists里面
- 按照结果分类:根据子查询得到的数据进行分类(理论上任何一个查询得到的结果都可以理解为二维表)
- 标量子查询:子查询得到的结果是一行一列。(出现在where之后)
- 列子查询:子查询得到的结果是一列多行。(出现在where之后)
- 行子查询:子查询得到的结果是多列一行(多行多列)(出现在where之后)
- 表子查询:子查询得到的结果是多行多列(出现的位置在From之后)
- 按位置分类:子查询(select语句)在外部查询(select语句)中出现的位置。
- 示例脚本
-- 创建班级表 CREATE TABLE my_class( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键', c_name ) NOT NULL COMMENT '班级名字', room ) NOT NULL COMMENT '班级所在教室' ); -- 插入班级信息 INSERT INTO my_class VALUES (NULL,'java001班','A01'); INSERT INTO my_class VALUES (NULL,'Linux003班','C15'); INSERT INTO my_class VALUES (NULL,'c005班','B23'); -- 创建学生表 CREATE TABLE my_student( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键', NAME ) NOT NULL COMMENT '学生姓名', age INT NOT NULL COMMENT '学生年龄', gender ) NOT NULL COMMENT '学生性别', c_id INT COMMENT '外键' , CONSTRAINT fk_c_id FOREIGN KEY (c_id) REFERENCES my_class (id) ); -- 插入学生信息 ,); ,); ,); ,); ,); ,);
3.1 标量子查询
- 示例:查询java001班的所有学生。
- ①确定数据源:获取所有的学生
select * from my_student where c_id = ?;
- ②获取班级id:可以通过名字确定。
SELECT id FROM my_class WHERE c_name = 'java001班' ; -- 一行一列
- ③最后的执行SQL语句
SELECT * FROM my_student WHERE c_id = (SELECT id FROM my_class WHERE c_name = 'java001班' );
3.2 列子查询
- 示例:查询所有在读班级的学生(班级表中存在的班级)
- ①确定数据源:学生
SELECT *FROM my_student WHERE c_id IN (?);
- ②确定有效班级的id:所有班级的id
SELECT id FROM my_class
- 最后的执行SQL语句
SELECT *FROM my_student WHERE c_id IN (SELECT id FROM my_class);
- 列子查询返回的结果会比较:一列多行,需要使用in作为条件匹配:其实在mysql中还有几个类似的条件:all、some、any。
3.3 行子查询
- 行子查询:返回的结果可以是多行多列(一行多列)
- 修改学生表
ALTER TABLE my_student ADD height INT NOT NULL COMMENT '身高'; ; ; ; ; ; ;
- 示例:要求查询整个学生中,年龄最大且身高
- 思路1:
- ①确定数据源
- 思路1:
select * from my_student where age = ? and height = ?;
- ②确定最大的年龄和最高的身高
select max(age),max(height) from my_student;
- ③最后的SQL执行语句
SELECT * FROM my_student WHERE (age = (SELECT MAX(age) FROM my_student)) AND (height = (SELECT MAX(height) FROM my_student));
- ④貌似上面的是对的哦,但是如果最高的年龄最大,身高最高的不是一个人呢?这样就不能查到数据呢,所以,综上所述,上面的思路貌似正确,但是不合题意。
- 思路2:正确解法
- 需要构造行元素:行元素是由多个字段构成。
SELECT * FROM my_student WHERE (age,height) = (SELECT MAX(age),MAX(height) FROM my_student);
3.4 表子查询
- 表子查询:子查询返回的结果是当做二维表来使用。
- 示例:找出每个班中最高的一个学生。
- ①先对学生按照身高降序
SELECT * FROM my_student ORDER BY height DESC
- ②对排序后的学生临时表按照班级分组
SELECT * FROM (SELECT * FROM my_student ORDER BY height DESC) AS student GROUP BY student.c_id;
- 当然,这一题可能有人会这样想?我先对学生分组,求出最大的年龄,然后用in子句,就可以了。
SELECT * FROM my_student WHERE height IN (SELECT MAX(height) FROM my_student GROUP BY c_id);
- 当然,第二种思路也是可以的。
3.5 exists子查询
- exists:是否存在,exists子查询是用来判断某些条件是否满足(跨表),exists是在where之后,exists返回的结果是0或1。
- 示例:查询所有的学生,前提条件是班级存在。
- ①确定数据源
SELECT * FROM my_student WHERE ?;
- ②确定条件是否满足
EXISTS(SELECT * FROM my_class)
- 最后的执行SQL语句
SELECT * FROM my_student WHERE EXISTS(SELECT * FROM my_class);
MySQL (六)--外键、联合查询、子查询的更多相关文章
-
MySQL数据库(4)_MySQL数据库外键约束、表查询
一.外键约束 创建外键 --- 每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任 ----主表 CREATE TABLE ClassCharger( id TINYINT PRIMARY ...
-
MySQL的查询,子查询,联结查询,联合查询
MySQL的查询,子查询,联结查询,联合查询 一.mysql查询的五种子句where(条件查询).having(筛选).group by(分组).order by(排序).limit(限制结果数) 二 ...
-
MySQL的外键,修改表,基本数据类型,表级别操作,其他(条件,通配符,分页,排序,分组,联合,连表操作)
MySQL的外键,修改表,基本数据类型,表级别操作,其他(条件,通配符,分页,排序,分组,联合,连表操作): a.创建2张表 create table userinfo(nid int not nul ...
-
MYSQL 查询方法 统计查询 链接查询 子查询
mysql表格查询方法: 查询: 1.简单查询 select * from Info --查所有数据select Code,Name from Info --查指定列的数据select Code as ...
-
吃货眼中的sqlalchemy外键和连表查询
前言 使用数据库一个高效的操作是连表查询,一条查询语句能够查询到多个表的数据.在sqlalchem架构下的数据库连表查询更是十分方便.那么如何连表查询?以及数据库外键对连表查询有没有帮助呢?本篇文章就 ...
-
MySQL(18):Select- subquery子查询
1. Select- subquery子查询 子查询:是将一条查询语句嵌套在另一条查询语句之中. 2. 案例 需求:查询获得代课天数最多的那个老师的信息. 思路:先获得最多的代课天数是多少天,然后再判 ...
-
MySQL数据库--外键约束及外键使用
什么是主键.外键关系型数据库中的一条记录中有若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键. 比如: 学生表(学号,姓名,性别,班级) 其中每个学生的学号是唯 ...
-
Python-select 关键字 多表查询 子查询
sql 最核心的查询语句!!!! 增删改 单表查询 select语句的完整写法 关键字的书写顺序 执行顺序 多表查询 笛卡尔积 内连接 左外连接 右外连接 全外连接 通过合并左外连接和右外连接 子查询 ...
-
第二百八十节,MySQL数据库-外键链表之一对多,多对多
MySQL数据库-外键链表之一对多,多对多 外键链表之一对多 外键链表:就是a表通过外键连接b表的主键,建立链表关系,需要注意的是a表外键字段类型,必须与要关联的b表的主键字段类型一致,否则无法创建索 ...
-
【知识库】-数据库_MySQL之基本数据查询:子查询、分组查询、模糊查询
简书作者:seay 文章出处: 关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询 回顾:[知识库]-数据库_MySQL常用SQL语句语法大全示例 Learn [已经过测试校验] 一.简单查询 ...
随机推荐
-
phpmyadmin not found
在 ubuntu 14.04 中使用: > sudo apt-get install phpmyadmin 安装好 phpmyadmin 之后,打开 http://localhost/phpmy ...
-
sublime2使用jshint
合理配置Jshint可以帮助写出高质量的代码,通过sublime2插件 JSHint Gutter 可以迅速提供开发效率和减少bug的个数. 1.安装JSHint Gutter插件 sublime2按 ...
-
tp文件上传;org/RBAC.class.php 权限类;think/page,class,php分页类;
一.上传表单: 注意,要使用上传功能 你的表单需要设置 enctype="multipart/form-data" <form action="__URL__/up ...
-
在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别
不少同学问,不都是刷新吗?还有什么区别?其实,还是有的. 其中,在地址栏按回车又分为两种情况.一是请求的URI在浏览器缓存中未过期,此时,使用Firefox的firebug插件在浏览器里显示的HTTP ...
-
[Angular 2] Component relative paths
Oingial aritial --> Link Take away: import { Component, OnInit } from '@angular/core'; @Component ...
-
windows转储文件(dmp)
1. 何为转储文件 转储文件也就是我们常说的dump文件.可以把转储文件看成软件的某个时刻的一个快照.转储文件一般都是在软件出现问题时手动生成或者程序自动生成.下面我们介绍几种生成转储文件的 ...
-
Windows上安装nvm--nodejs版本管理器
nvm最新的下载地址 Node版本管理器--nvm,可以运行在多种操作系统上.nvm for windows 是使用go语言编写的软件. 我电脑使用的是Windows操作系统,所以我要记录下在此操作系 ...
-
【Python3.6+Django2.0+Xadmin2.0系列教程之三(入门篇-下)】学生信息管理系统
上一篇我们已经初步的构建起了一个学生管理系统的模型,现在接着来继续完善它吧. 1.上传图片/文件等资源 有时候需要添加一些附件,例如,新生刚入学,大家相互之间还不熟悉,希望能通过照片来加深印象,并且方 ...
-
(原创)cocos2dx-lua TableView官方demo分析
本来是想看看网上的教程文章,结果看了好几篇,复制代码各种报错,有很多不存在的类和变量,根本用不了. 所以干脆自己去看官方demo,经过自己分析测试,已经大概会用了,顺便记录一下. 以下是代码,复制粘贴 ...
-
MyBatis-Plugins 的创建流程与执行顺序
一.插件的解析,所有插件都会被添加到 InterceptorChain 类中,用于后续处理 org.apache.ibatis.builder.xml.XMLConfigBuilder private ...