MySQL多表操作

Hi, guys!yeah,it's me again!

1. 表关系的概述

1. 1 表关系的概念

  1. 现实生活中, 实体与实体之间肯定是有关系滴, 比如部门和员工、老师和学生等, 我们在设计表的时候, 就应该体现出表与表之间的这种关系
表关系 案例
一对多 最常用的关系, 部门和员工
多对多 学生选课表 和 学生表,
一对一 相对使用比较少, 员工表, 简历表等
  1. 一对多建表原则: 在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
  2. 多对多建表原则: 需要创建第三张表, 中间表中至少两个字段, 这两个字段分别作为外键指向各自一方的主键
    >4.一对一: 在实际的开发中应用不多, 因为一对一可以创建成一张表
    原则①: 外键唯一: 主表的主键和从表的外键(唯一), 形成主外键关系, 外键唯一UNIQUE
    原则②: 外键是主键: 主表的主键和从表的主键, 形成主外键关系

2. 数据库设计

2.1 数据规范化

  1. 什么是范式:
    好的数据库设计对数据的存储性能和后期的程序开发,都会产生重要的影响, 建立科学的, 规范的数据库就要满足一些规则来优化数据的设计和存储, 这些规则就称为范式
  1. 三大范式
    目前数据库有六种范式: 第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)、第五范式(5NF, 又称为完美范式); 满足最低要求的范式是第一范式(1NF), 在第一范式的基础上进一步满足更多规范要求的成为第二范式, 其余范式以此类推, 一般说来, 数据库只需要满足第三范式就行了。
  1. 1NF: 数据库表的每一列都是不可分割的原子数据项, 不能是集合、数组等非原子数据项。即表中的某个列有多个值时,必须拆分成不同的列, 简而言之, 第一范式每一列不可再拆分,称为原子性
  2. 2NF: 在满足第一范式的前提下,表中的每一个字段都完全依赖于主键,第二范式的特点: ①: 一张表只描述一件事情; ②: 表中的每一列都完全依赖于主键。
  3. 3NF: 不产生传递依赖, 表中每一列都直接依赖与主键, 而不是通过其他列间接依赖与主键。

3. 数据准备

# 创建部门表
CREATE TABLE dept(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20)
);

# 向dept部门表中增加三条数据
INSERT INTO dept(NAME) VALUES('研发部'),('市场部'),('财务部');

# 创建员工表
CREATE TABLE emp(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(10),
    gender CHAR(1), # 性别 
    salary DOUBLE,  # 工资
    join_date DATE, # 入职日期
    dept_id INT,
    FOREIGN KEY(dept_id) REFERENCES dept(id)  # 外键,关联部门表(部门表的主键)
);

# 插入数据
INSERT INTO emp(NAME, gender, salary, join_date, dept_id) VALUES 
('张三','男','7200','2013-02-24', 1),
('李四','男','3600','2010-12-02', 2),
('王五','男','9000','2008-08-08', 2),
('丽娜','女','5000','2015-10-07', 3),
('萌萌','女','4500','2011-03-14', 1);

3.1 多表查询的分类

- 内连接: 1- 隐式内连接, 2- 显示内连接
- 外连接: 1- 左外连接, 2- 右外连接

3.2 笛卡尔积

# 查询所有的员工和所有的部门
SELECT * FROM emp, dept;
- 你会发现上面的sql语句查询以后, 显示的内容, 例如: 张三每个部门都有一个, 这种情况就是笛卡尔积
- 如何解决呢?
  - 我们在创建emp, dept表的时候设置了主键, 这时候就排上用场了, 当员工表.dept.id=部门表.id的数据才是我们想要的, 


# 第一步: 设置过滤条件
SELECT * 
FROM emp, dept 
WHERE emp.dept_id = dept.id;

# 第二步: 查询员工和部门的名字
SELECT emp.name, dept.name 
FROM emp, dept
WHERE emp.dept_id = dept.id;

3.3 内链接

用左边表的记录去匹配右边表的记录, 如果符合条件的则显示

  1. 隐式内连接: 看不到JOIN关键字,条件使用WHERE指定:
    格式: SELECT 字段名 FROM 左表,右表 WHERE 条件;
  2. 显示内连接: 使用INNER JOIN...ON语句, 可以省略INNER
    格式:SELECT 字段名 FROM 左表 [INNER] JOIN 右表 ON 条件;

# 查询张三的所有信息,包括所在的部门名称
# 第一步: 先确定要使用的表
SELECT * FROM emp JOIN dept;
# 第二步: 确定表连接条件, emp.dept_id = dept.id的数据才是有效的
SELECT * FROM emp e JOIN dept d ON e.dept_id = d.id;
# 第三步:最终确定查询张三的信息
SELECT * FROM emp e JOIN dept d ON e.dept_id = d.id WHERE e.name='张三';
# 第四步(非必须):中国文化博大精深
SELECT e.id 员工编号, e.name 员工姓名, e.gender 性别, e.salary 薪水, e.join_date 入职时间, e.dept_id 部门编号, d.name 部门名称
FROM emp e JOIN dept d ON e.dept_id = d.id 
WHERE e.name='张三';

总结内连接查询步骤: 1. 确定查询哪些表; 2. 确定表连接的条件; 3. 确定查询的条件; 4. 确定查询的字段。

3.4 外连接

  1. 左外连接:使用LEFT [OUTER] JOIN...ON, OUTER可以省略
    格式: SELECT 字段名 FROM 左表 LEFT [OUTER] JOIN 右表 ON 条件;
    用左表的记录去匹配右边表的记录, 如果符合条件的则显示:否则, 显示NULL,
# 测试左外连接: 插入一个新的部门[目前销售部没有员工]
INSERT INTO dept(NAME) VALUES ('销售部');
SELECT * FROM dept;

# 正式测试左外连接(比较下面的代码显示效果有何不同)
SELECT * FROM emp e LEFT JOIN dept d ON d.id = e.dept_id;
SELECT * FROM dept d LEFT JOIN emp e ON e.dept_id = d.id ;

2.左外连接:使用RIGHT[OUTER] JOIN...ON, OUTER可以省略
格式: SELECT 字段名 FROM 左表 RIGHT [OUTER] JOIN 右表 ON 条件;
用右表的记录去匹配左表的记录, 如果符合条件的则显示:否则, 显示NULL,

# 测试右外链接: 插入一个新的员工, 不给他分配部门
INSERT INTO emp VALUES (NULL, '赵六', '男', 6666, '2013-11-05', NULL);
SELECT * FROM emp;

# 正式测试右外连接(比较下面的代码显示有何不同)
SELECT * FROM emp e RIGHT JOIN dept d ON d.id = e.dept_id; 
SELECT * FROM dept d RIGHT JOIN emp e ON e.dept_id = d.id ;

4. 子查询

  1. 概念: ①一个查询的结果作为另外一个查询的条件;②有查询的嵌套, 内部的查询成为子查询; ③子查询要使用括号
子查询的结果 操作形式
单行单列 结果肯定在WHERE后面最为条件, 父查询使用: 比较运算符进行查询
多行单列 结果集类似于一个数组, 父查询使用IN运算符
多行多列 结果放在FROM后面作为表
# 单行单列测试案例
# 格式: SELECT 查询字段 FROM 表 WHERE 字段=(子查询);

# 查询所有员工中谁的工资最高
# 第一步: 找到最高的工资
SELECT MAX(salary) FROM emp;
# 第二步: 将第一步的结果作为WHERE的条件
SELECT NAME, salary FROM emp
WHERE salary=(SELECT MAX(salary) FROM emp);

# 多行单列测试案例
# 格式: SELECT 查询字段 FROM 表 WHERE 字段 IN (子查询);

# 查询工资低于7000的员工来自于哪些部门
# 第一步; 找到工资低于7000的员工所在部门编号
SELECT NAME, dept_id
FROM emp
WHERE salary < 7000;
# 第二步: 第一步的结果作为条件进行查询
SELECT NAME
FROM dept
WHERE id IN (SELECT dept_id FROM emp WHERE salary < 7000);

# 多行多列测试案例
# 格式: SELECT 查询字段 FROM (子查询) 表别名 WHERE 条件;

# 查询2011年以前入职的员工信息, 包括部门名称
# 第一步: 查询2011年以前入职的员工
SELECT * FROM emp WHERE join_date < '2011';
# 第二步: 查询所有的部门信息, 第一步的员工信息中的dept_id与dept中的id相同的输出
SELECT * 
FROM dept d, (SELECT * FROM emp WHERE join_date < '2011') e1
WHERE e1.dept_id=d.id;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容

  • 多表 单表:有冗余问题,同一个字段中出现大量的重复数据实际开发中,一个项目通常需要很多张表才能完成。例如一个商城项...
    YMeng_Zhang阅读 496评论 0 2
  • 联合查询 连接查询 子查询 示例 不管是大型还是小型项目,一个数据库里都会有N张表,表之间也通过一对一、多对一或者...
    Ly3911阅读 1,070评论 0 1
  • 外键约束 唯一约束和主键约束 唯一约束:列表内容必须唯一,但是可以为空 unique不能作为其它表的外键可以有多...
    强某某阅读 839评论 0 0
  • [TOC] 第一章:MySQL介绍 1.1-什么是SQL Structured Query Language 结构...
    雷哒哒阅读 1,293评论 0 3
  • 数据库对于后端开发来说是必不可少所要用到的,而MySQL数据库是其中的主流之一,在中小型公司中使用的较为广泛,作为...
    Steven_SHH阅读 1,459评论 0 2