mySQL入门之多表操作
外键
初识外键
外键:引用另一个表中的一列或多列,被引用的列应该具有主键约束或唯一性约束。(外键用于建立和加强两个表数据之间的连接,保证数据的完整和统一性)
主表:被引用的表
从表:引用外键的表
--例:
CREATE DATABASE duobiao;
USE duobiao;
CREATE TABLE grade(
id INT(4) NOT NULL PRIMARY KEY,
name VARCHAR(20));
CREATE TABLE student(
sid INT(5) NOT NULL PRIMARY KEY,
sname VARCHAR(20),
gid INT(4) NOT NULL,
foreign key(gid)references grade(id)
);
--student表中的gid是引用了grade表中主键(id),即:gid可以作为student表的外键,student表可以用gid连接grade表中的信息,从而建立两个表数据之间的连接。
--此两个表的主从关系为:grade为主表,student为从表
为表添加外键约束
语法: alter table 表名 add constraint 外键名 foreign key(外键字段名) REFERENCES 主表表名(主键字段名);
--例:
alter table student add constraint RE_ID foreign key(gid) REFERENCES grade(id);
--查看结果:show create table student;

删除外键约束
alter table 表名 drop foreign key 外键名;
--例:
alter table student drop foreign key RE_ID;
--查看结果:show create table student;
外键的注意事项:
1.建立外键的表必须是InnoDB型,不能是临时表。因为mySQL中只有InnoDB类型的表才支持外键。
2.定义外键名时,不能加引号,如:constraint 'NN-ID’或constraint "NN-ID"都是错误的。
3.外键约束的参数:
(1)cascade:从主表删除或者更新且自动删除或更新从表中匹配的行
(2)set null:从主表删除或更新行,并设置从表中的外键行为null,如果使用该选项,必须保证子表列没有指定not null
(3)restrict:拒绝对主表的删除或更新操作。
(4)no action:标准SQL的关键字,在mysql中于restrict相同(默认值)xf
操作关联表
关联关系
在实际开发中,需要根据实体的内容设计数据表,实体间会有各种关联关系。所以根据实体设计的数据表之间也存在着各种关联关系,mySQL中数据表的关联关系有三种:多对一,多对多,一对一。
(1)多对一
例如:一个班级有多个学生,不能说一个学生属于多个班级。
两表间建立外键:在多对一的表关系中,应该将外键建在多的一方(如:学生),否则会造成数据的冗余
(2)多对多
例如:订单与商品,一个订单中可以有多个商品,一个商品可以放到多个订单中。
两表间建立外键:通常情况下,为了实现这种关系需要定义一张中间表(称为连接表),该表存在两个外键(分别参照商品表与订单表)。
(3)一对一
例如:身份证与人,一个人只能有一张身份证,一张身份证只能匹配到一个人。
两表间建立外键:首先,分清主从关系,从表需要主表的存在才有意义(身份证需要人存在才有意义),因此,人为主表,身份证为从表(在身份证表中建立外键)。
应用方面:
1.分割具有很多列的表
2.由于安全原因而隔离表的一部分
3.保存临时的数据,并且可以毫不费力地通过删除这些数据
添加数据
因为外键列只能插入参照列存在的值,所以如果要为两个表添加数据,就需要先为主表添加数据
--建立student表与grade表外键联系
alter table student add constraint RE_ID foreign key(gid) REFERENCES grade(id);
--查看结果
show create table student;
--为主表添加数据
INSERT INTO grade(id,name)VARCHAR(1,'一年级');
INSERT INTO grade(id,name)VARCHAR(2,'二年级');
--为从表添加数据
INSERT INTO student(sid,sname,gid)VALUES(1,'李四',1),(2,'张三',1),(3,'王五',2);
--查看结果
SELECT sname FROM student WHERE name='一年级';
删除数据
先删除从表中参照列的数据(改为NULL)或删除从表数据,然后删除主表数据
--在student表中,将一年级的学生全部删除
delete from student where sname='李四';
delete from student where sname='张三';
--在grade表中,将一年级删除
delete from grade where id=1;
--查看结果
select*from grade;
连接查询
在关系型数据库管理系统中,建立表时各个数据之间的关系不必确定,通常将每个实体的所有信息存放在一个表中,当查询数据时,通过连接操作查询多个表中的实体信息,当两个或多个表中存在相同的意义的字段时,便可以通过这些字段对不同的表进行连接查询,连接查询包括:交叉查询,内连接查询,外连接查询
交叉连接(少见)
交叉连接返回的结果是被连接的两个表中所有数据行的笛卡儿积即:返回第一个表中符合查询条件的数据行数乘以第二个表符合查询条件的数据行数
语法:SELECT*FROM 表1 CROSS JOIN 表2;
CROSS JOIN用于连接两个要查询的表,该语句可以查询两个表中所有的数据组合。
--例:
--生成表
USE db2020
CREATE TABLE department(
did INT(4) NOT NULL PRIMARY KEY,
dname VARCHAR(36));
CREATE TABLE employee(
id INT(4) NOT NULL PRIMARY KEY,
name VARCHAR(36),
age INT(2),
did INT(4) NOT NULL);
--插入数据
INSERT INTO department(did,dname)VALUES(1,'IT部'),(2,'公关部'),(3,'人事部');
INSERT INTO employee VALUES(1,'张三',20,1),(2,'李四',20,2),(3,'王五',20,3);
--使用交叉连接查询
SELECT*FROM department CROSS JOIN employee;

内连接(简单连接或自然连接)
内连接使用比较运算符对两个表中的数据进行比较,并列出与连接条件匹配的数据行,结合成新的记录。
语法:SELECT 查询字段 FROM 表1 [INNER] JOIN 表2 ON 表1.关系字段=表2.关系字段;
INNER JOIN 用于连接两个表,ON来指定连接条件,其中INNER可以省略。
--例1:
SELECT employee.name,department.dname FROM department JOIN employee ON department.did=employee.did;

--例2:
--使用where条件语句来实现同样的功能
SELECT employee.name,department.dname FROM department,employee WHERE department.did=employee.did;

自连接查询(特殊的内连接):在一个连接查询中,涉及的两个表是同一个表。 例如:查询李四所在部门有哪些员工,就可以使用自连接查询
SELECT p1.* FROM employee p1 JOIN employee p2 ON p1.did=p2.did WHERE p2.name='李四';

外连接
返回查询结果不仅包含符合条件的数据,而且还包括左表(左连接),右表(右连接)或两个表(全外连接)中的所有数据,此时就需要使用外连接查询。
语法:SELECT 所查字段 FROM 表1 LEFT|RIGHT[OUTER] JOIN 表2 ON 表1.关系字段=表2.关系字段 WHERE 条件;
(1)LEFT JOIN(左连接)
返回查询结果:符合条件的数据和LEFT JOIN子句中指定的左表中所有记录,如果左表的某条记录在右表中不存在,则在右表中显示为空。
--例:
SELECT department.did,department.dname,employee.name FROM department LEFT JOIN employee ON department.did=employee.did;

(2)RIGHT JOIN(右连接)
返回查询结果:符合条件的数据和RIGHT JOIN子句中指定的右表中所有记录,如果右表的某条记录在左表中不存在,则在左表中显示为空。
SELECT department.did,department.dname,employee.name FROM department RIGHT JOIN employee ON department.did=employee.did;

复合条件连接查询
复合条件连接查询即:在连接查询的过程中,通过添加过滤条件来限制查询结果,使查询结果更加精确。
子查询
子查询:一个查询语句嵌套在另一个查询语句内部的查询。
它可以嵌套在一个SELECT,SELECT…INTO,INSERT…INTO等语句中。
执行过程:先执行子查询中的语句,然后将返回的结果作为外层查询的过滤条件。
在子查询中通常可以使用IN,EXISTS,ANY,ALL操作符。
带IN关键字的子查询
内层查询语句只返回一个数据列,这个数据列中的值将供外层语句进行比较操作。
--例:
SELECT*FROM department WHERE did IN(SELECT did FROM employee WHERE age=20);

带EXISTS关键字的子查询
EXISTS关键字后面的参数可以是任意一个子查询,这个子查询的作用相当于测试,它不产生任何数据,只返回TRUE或FALSE,当返回值为TRUE时,外层语句才会执行。
带ANY的关键字的子查询
ANY关键字允许创建一个表达式对子查询的返回值进行比较,只要满足内层子查询中任意一个比较条件,就返回一个结果作为外层查询条件。
--例:
SELECT*FROM department WHERE did>any(select did from employee);

带ALL关键字的子查询
ALL关键字与ANY有点类似,只不过带ALL关键字的子查询返回的结果需同时满足所有内层查询条件。
--例:
SELECT*FROM department WHERE did>all(select did from employee);

带比较运算符的子查询
前面的ANY和ALL关键字的子查询中都使用了比较运算符,常见的有:>,<,>=,!=等
mySQL入门之多表操作的更多相关文章
- Python/MySQL(二、表操作以及连接)
Python/MySQL(二.表操作以及连接) mysql表操作: 主键:一个表只能有一个主键.主键可以由多列组成. 外键 :可以进行联合外键,操作. mysql> create table y ...
- MySQL之库、表操作
一.库操作 创建库 create database 库名(charset utf8 对库的编码进行设置,不写就用默认值) 库名可以由字母.数字.下划线.特殊字符,要区分大小写,唯一性,不能使用关键字, ...
- MySQL(分组、连表操作、备份数据库)
day58 分组 参考:https://www.cnblogs.com/xp796/p/5262187.html select dept, max(salary) from department gr ...
- MySql基础学习-库表操作
1.创建数据 CREATE DATABASE mysql_study; 2.连接数据库 USE mysql_study 3.创建数据表 CREATE TABLE person( id int auto ...
- MYSQL基础笔记(三)-表操作基础
数据表的操作 表与字段是密不可分的. 新增数据表 Create table [if not exists] 表名( 字段名 数据类型, 字段名 数据类型, 字段n 数据类型 --最后一行不需要加逗号 ...
- django连接mysql数据库以及建表操作
django连接mysql数据库需要在project同名的目录下面的__init__.py里面加入下面的东西 import pymysql pymysql.install_as_MySQLdb() 找 ...
- MySQL入门第二天——记录操作与连接查询
常见SQL语法,请参见w3school:http://www.w3school.com.cn/sql/sql_distinct.asp 易百教程:http://www.yiibai.com/sql/f ...
- mysql,数据类型与表操作
一.mysql基本认知 创建用户 create host aa identified with mysql_native_password by ''; 修改用户权限 alter user root@ ...
- MyBatis实现Mysql数据库分库分表操作和总结
前言 作为一个数据库,作为数据库中的一张表,随着用户的增多随着时间的推移,总有一天,数据量会大到一个难以处理的地步.这时仅仅一张表的数据就已经超过了千万,无论是查询还是修改,对于它的操作都会很耗时,这 ...
随机推荐
- 1到n整数中1出现的次数
1到n整数中1出现的次数 题目描述 输入一个整数n, 求1~n这n个整数的十进制表示中1出现的次数. 例如, 输入12, 1~12这些整数中包含1的数字有1, 10, 11和12, 1一共出现了4次 ...
- 面试 之 nginx,负载,动静分离
大家先看这个逻辑图 为什么我们要这样去架构我们的一个项目呢? 这样做的话,动态请求要先访问 A,A 转发访问 B,再由 B 返回结果给 A,A 最后又将结果返回给客户端这样是不是很麻烦? 最初开发的时 ...
- streamreader
using (StreamReader sr = new StreamReader(@"C:\Documents and Settings\Administrator\桌面\1.txt&qu ...
- 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(1) - 执行在不同CM内核下
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(1)之执行在不同CM内核下. 文接上篇 <RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计&g ...
- Activit的心路历程:获取当前节点的下一节点【可能存在多个】的nodeId
上一任务节点 在我的开发任务中,突然给我提出了一个待办任务需要获取当前任务节点下一任务节点的表单信息,刚开始搞得我有点措手不及,后来仔细是靠后,灵感一下,直接操作流程的bpmn信息就可以获取到节点信息 ...
- C语言I博课作业04
这个作业属于哪个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2020-1/homework/11489 我在这个作业课程 ...
- tcp 拥塞控制引擎&状态机
TCP核心:流量控制 拥塞控制 流量控制:滑动窗口来实现, 防止接收方能够处理过来 拥塞控制:防止过多的包被发送到网络中,避免出现网络负载过大 说一说 拥塞控制: 拥塞控制状态机的状态有五种,分别 ...
- quic是干什么的?
什么是quic? quic解决了什么问题?HTTP和QUIC QUIC :Quick UDP Internet Connections:是一种新的默认加密的互联网通信协议,它提供了许多改进,旨在加速H ...
- Python_科学计算平台__pypi体系的numpy、scipy、pandas、matplotlib库简介
1.numpy--基础,以矩阵为基础的数学计算模块,纯数学 存储和处理大型矩阵. 这个是很基础的扩展,其余的扩展都是以此为基础. 快速学习入口 https://docs.scipy.org/doc/n ...
- python学习--sys.argv
sys.argv是获取命令行参数的: sys.argv[0]表示代码本身文件路径:从1开始获取参数. import sysprint (sys.argv[0])count = int(sys.argv ...