1 2 3 4

MySQL 多键

1.外键: 用来建立两张表之间的关系
- 一对多
- 多对多
- 一对一

2.了解知识点:
- 修改表的操作
- 复制表操作

研究表与表之间的关系:
1.定义一张 员工部门表
id, name, gender, dep_name, dep_desc

- 将所有数据存放在一张表中的弊端:
1.结构不清晰 ---> 不致命
2.浪费空间 ---> 不致命
3.可扩展性极差 ---> 不可忽视的弊端
- 类似于将所有python代码存放在一个py文件中,强耦合到一起了----> 解耦合 ----> 拆分表

- 拆分表解决以上问题.

- 需要给两张表之间,建立一种强有力的关系, 使用 “外键”

- !!!!! ****** 如何确认表与表之间的关系是 (一对多、多对多、一对一)
- 注意: 要确立两张表之间的关系,必须站在两个位置去思考:
- 站在员工表的位置: 多个员工能否对应一个部门? 能!!!

- 员工与部门: 多 对 一

- 员工表单向 多 对 一 部门表

- 站在部门表的位置: 多个部门能够对应一个员工? 不能!!!

总结: 凡是单向 多 对 一 的表关系,称之为 一对多 的外键关系。

- 外键: 语法: foreign key(当前表中建立关系的外键字段) references 被关联表名(id)

创建两张表

1.必须先建立被关联表,再建立关联表

被关联表:

dep:
create table dep(
id int primary key auto_increment,
dep_name varchar(16),
dep_desc varchar(255)
);

关联表:

emp:
create table emp(
id int primary key auto_increment,
name varchar(16),
age int,
gender enum('male', 'female', 'others') default 'male',
dep_id int not null,
foreign key(dep_id) references dep(id)
);

插入数据:

- 1.必须先插入被关联表(dep)的数据,再插入关联表(emp)的数据。

dep:

insert into dep(dep_name, dep_desc) values('nb_外交部', '国际形象大使部门'),
('sb_教学部', '造程序员部门!!!!'),
('技术部', '技术有限部门');

emp:

insert into emp(name, age, gender, dep_id)
values('tank', 17, 'male', 1),
('jason', 70, 'male', 2),
('sean', 50, 'male', 2),
('egon', 88, 'male', 2),
('owen', 95, 'female', 3);

报错,

insert into emp(name, age, gender, dep_id) values('大饼', 100, 'others', 999);

更新数据或删除数据

- 更新数据
# 报错
update emp set dep_id=100 where id=2;
# 报错
update dep set id=100 where id=1;

先删除已关联的dep_id字段,才能修改dep表中的关联id字段。

delete from emp where id=1;
update dep set id=100 where id=1;

删除: 先删除关联表中的记录,在删除被关联表中的记录

- 删除emp表中的dep_id为2的记录
delete from emp where dep_id=2;

- 再删除dep表中id为2的记录
delete from dep where id=2;

- 级联更新与级联删除
- on update cascade
- on delete cascade
- 创建表
# 被关联表:
dep2:
create table dep2(
id int primary key auto_increment,
dep_name varchar(16),
dep_desc varchar(255)
);

关联表:

emp2:
create table emp2(
id int primary key auto_increment,
name varchar(16),
age int,
gender enum('male', 'female', 'others') default 'male',
dep_id int not null,
foreign key(dep_id) references dep2(id)
on update cascade
on delete cascade
);

- 插入数据
# dep:
insert into dep2(dep_name, dep_desc) values('nb_外交部', '国际形象大使部门'),
('sb_教学部', '造程序员部门!!!!'),
('技术部', '技术有限部门');

emp:

insert into emp2(name, age, gender, dep_id)
values('tank', 17, 'male', 1),
('jason', 70, 'male', 2),
('sean', 50, 'male', 2),
('egon', 88, 'male', 2),
('owen', 95, 'female', 3);

报错,

insert into emp(name, age, gender, dep_id) values('大饼', 100, 'others', 999);

- 更新数据或删除数据
- 更新记录
update dep2 set id=200 where id=1;

- 删除记录
delete from dep2 where id=200;

注意: mysql中没有 多对一 只要 一对多

- 多对多:
也必须站在两张表的位置去思考;

- 错误示范:
- 创建book表
create table book(
id int primary key auto_increment,
title varchar(20),
price int,
book_content varchar(255),
author_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade
);

- 创建author表
create table author(
id int primary key auto_increment,
name varchar(16),
age int,
book_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade
);

- 问题: 无法知道哪张表是被关联表

- 利用第三张表,为两张表建立“多对多外键关系”。
- book:
create table book(
id int primary key auto_increment,
title varchar(20),
price int,
book_content varchar(255)
);

- author:
create table author(
id int primary key auto_increment,
name varchar(16),
age int
);

- book2author:
create table book2author(
id int primary key auto_increment,
book_id int,
author_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade,
foreign key(author_id) references author(id)
on update cascade
on delete cascade
);

- 插入数据
- book
insert into book(title, price, book_content) values
('金瓶mei', 199, '讲述朦胧时光的小故事'),
('python从入门到断气', 2000, '学习如何一夜秃头'),
('三体', 200, '跟着大佬进入宇宙奇幻世界')
;

- author
insert into author(name, age) values
('egon', 68),
('jason', 88);

- book2author:
insert into book2author(book_id, author_id) values
(1, 1),
(1, 2),
(2, 2),
(3, 1);

报错, 插入的数据,book_id, author_id必须存在

insert into book2author(book_id, author_id) values (4, 4);

更新或删除

更新

- update book set price=6666 where id=1;
- update book set id=4 where id=1;

删除

- delete from book where id=4;

- 一对一:
- 两张之间的关系 一一对应,将一张数据量比较大的表,拆分成两张表。
- user_info:
id, name, age, gender, hobby, id_card

- user:
id , name, age, detail_id(外键)

- detail:
id, gender, hobby, id_card

user与detail表建立了 一对一的外键 关系。
foreign key 应该建在 使用频率较高的一方。

- 创建表
# 被关联表
create table customer(
id int primary key auto_increment,
name varchar(16),
media varchar(32)
);
# 关联表
create table student(
id int primary key auto_increment,
addr varchar(255),
phone char(11),
id_card char(18),

外键必须设置为唯一的

customer_id int unique,
foreign key(customer_id) references customer(id)
on update cascade
on delete cascade
);

- 插入数据
insert into customer(name, media) values
('hcy', 'facebook'),
('zsb1', 'ig'),
('zsb2', 'vk'),
('hb', '探探');

insert into student(addr, phone, id_card, customer_id) values
('上海', '15214546711', '440888888888888888', 1),
('北京', '18888888888', '440777777777777777', 2);

报错,一对一,关系必须 一一对应

insert into student(addr, phone, id_card, customer_id) values ('上海', '15214546711', '440888888888888888', 1);

了解:

- 修改表的操作

  - 语法:  注意: mysql 关键字不区分大小写

    1. 修改表名

       ALTER TABLE 表名  RENAME 新表名;

    2. 增加字段
       ALTER TABLE 表名
       ADD 字段名 数据类型 [完整性约束条件…],
       ADD 字段名 数据类型 [完整性约束条件…];  # 添加到最后一列

       ALTER TABLE 表名
       ADD 字段名 数据类型 [完整性约束条件…] FIRST;  # 添加到第一列

       ALTER TABLE 表名
       ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;  # 添加到某一列之后

    3. 删除字段
       ALTER TABLE 表名
       DROP 字段名;

    4. 修改字段
       ALTER TABLE 表名
       MODIFY 字段名 数据类型 [完整性约束条件…];  # 修改数据类型

       ALTER TABLE 表名
       CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];  # 修改字段名,保留字段类型

       ALTER TABLE 表名
       CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];  # 修改字段名与字段类型

- 复制表的操作:
  复制表结构+记录 (key不会复制: 主键、外键和索引)
  mysql> create table new_service select * from service;

  只复制表结构

  将select * from service where 1=2; ---> 不要真实数据,需要表结构

  mysql> create table new_customer select * from customer where 1=2;  这个只是复制表的结构
posted @ 2019-12-14 18:09  ^更上一层楼$  阅读(491)  评论(0)    收藏  举报