修改mysql 外键_MySQL之外键简介和修改表

本文介绍了MySQL中外键的概念及其作用,强调了外键在建立表间关系中的重要性。通过实例展示了如何创建和使用外键,包括一对一、一对多和多对多关系,并解释了级联更新和级联删除的原理。此外,还讨论了如何修改表结构,如添加、删除和修改字段。
摘要由CSDN通过智能技术生成

1.什么是外键?

外键是用来建立两张表之间的关系

2.为什么要有外键?

举个栗子:

先定义一张表

id

name

gender

dep_name

dep_desc

1

tank

male

技术部

技术有限部门

2

sean

female

销售部

销售丝袜

3

egon

female

销售部

销售丝袜

将所有数据存放在一张表中的弊端:

1.结构不清晰

2.浪费空间

3.可扩展性极差 ---> 不可忽视的弊端

类似于将所有python代码存放在一个py文件中,强耦合到一起了,代码解耦合就相当于 拆分表

拆分表解决以上问题.

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

2.怎么使用外键?

先创建两张表(将一张表拆分成两张),确认两张表的关系(关系如下)

一对多

多对多

一对一

注意:确立两张表的关系必须站在两个位置去思考:

即:站在员工表的位置: 多个员工能否对应一个部门?(很明显可以)

员工与部门: 多 对 一

员工表单向 多 对 一 部门表

站在部门表的位置: 多个部门能够对应一个员工?(也很明显不能)

部门与员工:一 对 多

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

2)创建两张表,必须先建立被关联表,再建立关联表

重点:外键语法:

foreign key (当前表中建立关系的外键字段) references 被关联表明(id)

fc91253219fb5039c116ed39428595da.png

一对多关系

先创建被关联表:

create table dep(

id int primary key auto_increment,

dep_name varchar(16),

dep_decs varchar(255)

);

再创建关联表:

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)

);

576d3a98018396fc1a199bd3d2b26bcd.png

建立好表格和再插入数据

先插入被关联表(dep)的数据,再插入关联表(emp)的数据

被关联表:

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

关联表:

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);

补充:跟新数据:

在没有特殊设置的情况下除了表中的关联字段(dep_id和emp表中的id)都可以跟新

update dep set dep_name='nb_外联部' where id=1;

报错:

# 报错update emp set dep_id=100 where id=2;

# 报错update dep set id=100 where id=1;

报错信息:ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`db1`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`dep_id`) REFERENCES `dep` (`id`))

方法一:

可以在开始dep_id不强制设置not null的情况下将dep_id修改为null,使其不关联emp,这样emp中的关联id也可以进行修改

update emp set dep_id=null where id=3;#先修改为null

update dep set id=100 where id=2;# 再修改被关联表的id

这样就不会报错

方法二:

先删除已关联的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);

4.修改表的操作

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

修改表名

ALTER TABLE 表名

RENAME 新表名;

增加字段

ALTER TABLE 表名

ADD 字段名 数据类型 [完整性约束条件…],

ADD 字段名 数据类型 [完整性约束条件…]; # 添加到最后一列

ALTER TABLE 表名

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

ALTER TABLE 表名

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

删除字段

ALTER TABLE 表名

DROP 字段名;

修改字段

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;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值