数据库语法二之外键
外键(******必备知识点******): 1、外键:用来建立两张表之间的关系 - 一对多 - 多对多 - 一对一 2、了解的知识点: - 修改表的操作 - 赋值表操作 研究表与表之间的关系: 1、定义一张员工表,员工部门表 id,name,gender,dep_name,dep_desc - 将所有数据存放在一张表中的弊端; 1、结构不清晰:---不致命 2、浪费空间:----不致命 3、可扩展性差----不可忽视的弊端 - 类似于将所有的python代码存放到一个py文件中,强耦合到一起 - 拆分表解决以上问题 - 需要给两张表之间,建立一种强有力的关系,这就得使用外键 -!!!!注意:如何确认表与表之间的关系是(一对多,多对多,一对一) - 注意:要确立两张表之间的关系,必须站在两个位置去思考 - 站在员工表达位置:多个员工能否对应一个部门?能! 员工与部门:多 对 一 员工表单向 多 对 一部门表 - 站在部门表的位置:多个部门能否对应一个员工? 不能!!! 总结:凡是单向 多 对 一 的表达关系,称之为 一对多的外键关系。因为python中的mysql中没有多对一的关系 - 外键:语法: foreign key(当前表中建立关系的外键字段) references 被关联表名(id) #####注意:创建两张表 必须先建立被关联表,在建立关联表 被关联表: 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', 50, 'male', 2), ('sean', 66, 'male', 2), ('egon', 73, 'male', 2), ('owen', 95, 'female', 3); # 当在关联表中查看时如果在key列中能看到MUL则代表外键绑定成功 # 若插入一条被关联数据中没有的id号,则会报错 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 emp2 where id=5; 注意: 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(20), 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', 588, '讲述朦胧时光的小故事'), ('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; ####注:此时的更新或删除只会对自己以及第三方的数据有影响, 并不会影响到其他的table # 删除 - 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 ('上海', '12345678912', '1466711446248431348', 1), ('北京', '12345678911', '1466711446248431349', 2); # 报错,一对一 关系必须一一对应 insert into student(addr, phone, id_card, customer_id) values ('上海', '12345678912', '1466711446248431348', 1) - 了解: - 修改表的操作: - 语法:注意:mysql 不区分大小写 1、修改表名 alter table 表名 rename 新的表名; 2、增加字段 alter table 表名 add 字段名 数据类型 (完整的约束条件), add 字段名 数据类型 (完整的约束条件); #添加到最后一列 alter table 表名 add 字段名 数据类型 (完整的约束条件) first; # 添加到第一列 alter table 表名 add 字段名 数据类型 (完整的约束条件) after 字段名; # 添加到某一列之后 3、删除字段 alert table 表名 drop 字段名; 4、修改字段 alter table 表名 modify 字段名 数据类型 (完整的约束条件); #修改数据类型 alter table 表名 change 旧字段名 新字段名 旧数据类型 (完整的约束条件); # 修改字段名,保留字段类型 alter table 表名 change 旧字段名 新字段名 新数据类型 (完整的约束条件); # 修改字段名与字段类型 复制表的操作: 复制表结构 + 记录 (key不会复制:主键、外键和索引) create table new_service select * from service; 只复制表结构 # 将select * from service where 1=2; -----> 不要真实数据,只需要表结构 create table new_customer select * from customer where 1=2;
来源:https://www.cnblogs.com/yafeng666/p/12030339.html