MySQL(基础命令7)

1.多表

1.1 多表简述

  • 实际开发中,一个项目通常需要很多张表才能完成。
  • 例如一个商城项目的数据库,需要有很多张表:用户表、分类表、商品表、订单表....

 1.2 单表的缺点

1.2.1 数据准备

1. 创建一个数据库 db3

CREATE DATABASE db3 CHARACTER SET utf8;

2. 数据库中 创建一个员工表 emp

  • 包含如下列 eid, ename, age, dep_name, dep_location
  • eid 为主键并 自动增长, 添加 5 条数据
-- 创建 emp 表 主键自增
CREATE TABLE emp(
eid INT PRIMARY KEY AUTO_INCREMENT ,
ename VARCHAR ( 20 ),
age INT ,
dep_name VARCHAR ( 20 ),
dep_location VARCHAR ( 20 )
);
-- 添加数据
INSERT INTO emp (ename, age, dep_name, dep_location) VALUES ( ' 张百万 ' , 20 , ' 研发
' , ' 广州 ' );
INSERT INTO emp (ename, age, dep_name, dep_location) VALUES ( ' 赵四 ' , 21 , ' 研发
' , ' 广州 ' );
INSERT INTO emp (ename, age, dep_name, dep_location) VALUES ( ' 广坤 ' , 20 , ' 研发
' , ' 广州 ' );
INSERT INTO emp (ename, age, dep_name, dep_location) VALUES ( ' 小斌 ' , 20 , ' 销售
' , ' 深圳 ' );
INSERT INTO emp (ename, age, dep_name, dep_location) VALUES ( ' 艳秋 ' , 22 , ' 销售
' , ' 深圳 ' );
INSERT INTO emp (ename, age, dep_name, dep_location) VALUES ( ' 大玲子 ' , 18 , ' 销售
' , ' 深圳 ' );

1.2.2 单表的问题

1. 冗余, 同一个字段中出现大量的重复数据

 1.3 解决方案

1.3.1 设计两张表

1. 多表方式设计

  • department 部门表 : id, dep_name, dep_location
  • employee 员工表: eid, ename, age, dep_id

2. 删除emp, 重新创建两张表

-- 创建部门表
-- 一方 , 主表
CREATE TABLE department(
id INT PRIMARY KEY AUTO_INCREMENT ,
dep_name VARCHAR ( 30 ),
dep_location VARCHAR ( 30 )
);
-- 创建员工表
-- 多方 , 从表
CREATE TABLE employee(
eid INT PRIMARY KEY AUTO_INCREMENT ,
ename VARCHAR ( 20 ),
age INT ,
dept_id INT
);

3. 添加部门表 数据

-- 添加 2 个部门
INSERT INTO department VALUES ( NULL , ' 研发部 ' , ' 广州 ' ),( NULL , ' 销售部 ' , ' 深圳 ' );
SELECT * FROM department;

4. 添加员工表 数据

-- 添加员工 ,dep_id 表示员工所在的部门
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 张百万 ' , 20 , 1 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 赵四 ' , 21 , 1 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 广坤 ' , 20 , 1 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 小斌 ' , 20 , 2 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 艳秋 ' , 22 , 2 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 大玲子 ' , 18 , 2 );
SELECT * FROM employee;

1.3.2 表关系分析

  • 部门表与员工表的关系

 

  • 员工表中有一个字段dept_id 与部门表中的主键对应,员工表的这个字段就叫做 外键
  • 拥有外键的员工表 被称为 从表 , 与外键对应的主键所在的表叫做 主表

1.3.3 多表设计上的问题

  • 当我们在 员工表的 dept_id 里面输入不存在的部门id ,数据依然可以添加 显然这是不合理的.
-- 插入一条 不存在部门的数据
INSERT INTO employee (ename,age,de

 

  • 实际上我们应该保证,员工表所添加的 dept_id , 必须在部门表中存在.
  • 解决方案:使用外键约束,约束 dept_id ,必须是 部门表中存在的id

1.4 外键约束

1.4.1 什么是外键

  • 外键指的是在 从表 中 与 主表 的主键对应的那个字段,比如员工表的 dept_id,就是外键
  • 使用外键约束可以让两张表之间产生一个对应关系,从而保证主从表的引用的完整性

  • 多表关系中的主表和从表
  • 主表: 主键id所在的表, 约束别人的表
  • 从表: 外键所在的表多, 被约束的表

 1.4.2 创建外键约束

语法格式:

1.新建表时添加外键

[ CONSTRAINT ] [ 外键约束名称 ] FOREIGN KEY ( 外键字段名 ) REFERENCES 主表名 ( 主键字段名 )

 2. 已有表添加外键

ALTER TABLE 从表 ADD [ CONSTRAINT ] [ 外键约束名称 ] FOREIGN KEY ( 外键字段名 ) REFERENCES
主表 ( 主 键字段名 );

3.重新创建employee, 添加外键约束

-- 先删除 employee
DROP TABLE employee;
-- 重新创建 employee , 添加外键约束
CREATE TABLE employee(
eid INT PRIMARY KEY AUTO_INCREMENT ,
ename VARCHAR ( 20 ),
age INT ,
dept_id INT ,
-- 添加外键约束
CONSTRAINT emp_dept_fk FOREIGN KEY (dept_id) REFERENCES department(id)
);

4. 插入数据

-- 正常添加数据 ( 从表外键 对应主表主键 )
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 张百万 ' , 20 , 1 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 赵四 ' , 21 , 1 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 广坤 ' , 20 , 1 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 小斌 ' , 20 , 2 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 艳秋 ' , 22 , 2 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 大玲子 ' , 18 , 2 );
-- 插入一条有问题的数据 ( 部门 id 不存在 )
-- Cannot add or update a child row: a foreign key constraint fails
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 错误 ' , 18 , 3 );
  • 添加外键约束,就会产生强制性的外键数据检查, 从而保证了数据的完整性和一致性

 1.4.3 删除外键约束

1.语法格式

alter table 从表 drop foreign key 外键约束名称

2.删除外键约束

-- 删除 employee 表中的外键约束 , 外键约束名 emp_dept_fk
ALTER TABLE employee DROP FOREIGN KEY emp_dept_fk;
3.再将外键 添加回来
语法格式
ALTER TABLE 从表 ADD [ CONSTRAINT ] [ 外键约束名称 ] FOREIGN KEY ( 外键字段名 ) REFERENCES
主表 ( 主 键字段名 );
-- 可以省略外键名称 , 系统会自动生成一个
ALTER TABLE employee ADD FOREIGN KEY (dept_id) REFERENCES department (id);

1.4.4 外键约束的注意事项

1. 从表外键类型必须与主表主键类型一致 否则创建失败.

 2. 添加数据时, 应该先添加主表中的数据.

-- 添加一个新的部门
INSERT INTO department(dep_name,dep_location) VALUES ( ' 市场部 ' , ' 北京 ' );
-- 添加一个属于市场部的员工
INSERT INTO employee(ename,age,dept_id) VALUES ( ' 老胡 ' , 24 , 3 );

3.  删除数据时,应该先删除从表中的数据.

-- 删除数据时 应该先删除从表中的数据
-- 报错 Cannot delete or update a parent row: a foreign key constraint fails
-- 报错原因 不能删除主表的这条数据 , 因为在从表中有对这条数据的引用
DELETE FROM department WHERE id = 3 ;
-- 先删除从表的关联数据
DELETE FROM employee WHERE dept_id = 3 ;
-- 再删除主表的数据
DELETE FROM department WHERE id = 3 ;

1.4.5 级联删除操作(了解)

  • 如果想实现删除主表数据的同时,也删除掉从表数据,可以使用级联删除操作
级联删除
ON DELETE CASCADE

1. 删除 employee,重新创建,添加级联删除

-- 重新创建添加级联操作
CREATE TABLE employee(
eid INT PRIMARY KEY AUTO_INCREMENT ,
ename VARCHAR ( 20 ),
age INT ,
dept_id INT ,
CONSTRAINT emp_dept_fk FOREIGN KEY (dept_id) REFERENCES department(id)
-- 添加级联删除
ON DELETE CASCADE
);
-- 添加数据
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 张百万 ' , 20 , 1 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 赵四 ' , 21 , 1 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 广坤 ' , 20 , 1 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 小斌 ' , 20 , 2 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 艳秋 ' , 22 , 2 );
INSERT INTO employee (ename, age, dept_id) VALUES ( ' 大玲子 ' , 18 , 2 );
-- 删除部门编号为 2 的记录
DELETE FROM department WHERE id = 2 ;
  • 员工表中 外键值是2的记录,也被删除了

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值