''' 定义一张员工表,表中有很多字段 id name gender dep_name dep_desc 1 mike male 外交部 漂泊游荡 2 jack male 教学部 教书 3 mali female 教学部 教书 4 egon male 教学部 教书 5 tank female 技术部 果实能力者 # 1:该表的组织结构不是很清晰(可忽视) 2:浪费硬盘空间(可忽视) >>>数据量大的话,部门和部门描述的数据都是重复的 3:数据的扩展性极差(无法忽视) >>>如果要修改一个部门名称,那么全部数据都要进行修改 如何优化?上述问题就类似于你将所有的代码都写在了一个py文件中 将员工表拆分成员工表和部门表 id name gender dep_id 1 mike male 1 2 jack male 2 3 mali female 2 4 egon male 2 5 tank female 2 id dep_name dep_desc 1 外交部 漂泊游荡 2 教学部 教书 3 技术部 果实能力者 外键 外键就是用来帮助我们建立表与表之间关系 foreign key 表关系 表与表之间最多只有四种关系 一对多关系 在MySQL的关系中没有多对一 一对多/多对一,都叫一对多 多对多关系 一对一关系 没有关系 '''

一对多关系
''' 判断表与表之间关系的时候,前期不熟悉的情况下,一定要按照建议进行换位思考,分别站在两张表的角度考虑 员工表与部门表为例 先站在员工表 思考一个员工能否对应多个部门(一条员工数据能否对应多条部门数据) 不能(不能直接得出结论,一定要两张表都考虑完全) 再站在部门表 思考一个部门能否对应多个员工(一个部门数据能否对应多条员工数据) 能 得出结论 员工表与部门表是单向的一对多,所以表关系就是一对多 foreign key 1:一对多表关系,外键字段建在多的一方(员工表) 2:在创建表的时候,一定要先建被关联表(部门表) 3:在录入数据的时候,也必须先录入被关联表(部门表) sql语句建立表关系 create table dep( id int primary key auto_increment, dep_name char(16), dep_desc char(32) ); create table emp( id int primary key auto_increment, name char(16), gender enum('male','female','others') default 'male', dep_id int, foreign key(dep_id) references dep(id) # emp表的dep_id字段与dep表的id字段有关联 ); insert into dep(dep_name,dep_desc) values('教学部','教书育人'),('外交部','多人外交'),('技术部','技术能力者'); insert into emp(name,dep_id) values('jason',2),('egon',1),('tank',1),('kevin',3); # 修改dep表里面的id字段 update dep set id=200 where id=2; 不行 # 删除dep表里面的数据 delete from dep; 不行 # 1:先删除教学部对应的员工数据,之后再删除部门 操作太过于繁琐 # 2:真正做到数据之间有关系 更新就同步更新 删除就同步删除 级联更新,级联删除 create table dep( id int primary key auto_increment, dep_name char(16), dep_desc char(32) ); create table emp( id int primary key auto_increment, name char(16), gender enum('male','female','others') default 'male', dep_id int, foreign key(dep_id) references dep(id) on update cascade # 同步更新 on delete cascade # 同步删除 ); insert into dep(dep_name,dep_desc) values('教学部','教书育人'),('外交部','多人外交'),('技术部','技术能力者'); insert into emp(name,dep_id) values('jason',2),('egon',1),('tank',1),('kevin',3); update dep set id=200 where id=2; delete from dep where id=1; '''
多对多关系
''' 图书表和作者表 create table book( id int primary key auto_increment, title varchar(32), price int, author_id int, foreign key(author_id) references author(id) on update cascade on delete cascade ); create table author( id int primary key auto_increment, name varchar(32), age int, book_id int, foreign key(book_id) references book(id) on update cascade on delete cascade ); 按照上述的方式创建,一个都别想成功!其实我们只是想记录书籍和作者的关系 针对多对多字段表关系,不能在两张原有的表中创建外键 需要你单独再开设一张表,专门用来存储两张表数据之间的关系 create table book( id int primary key auto_increment, title varchar(32), price int ); create table author( id int primary key auto_increment, name varchar(32), age int ); create table book_to_author( id int primary key auto_increment, author_id int, book_id int, foreign key(author_id) references author(id) on update cascade on delete cascade, foreign kry(book_id) references book(id) on update cascade on delete cascade ); '''


一对一关系
''' id name age addr phone hobby email... 如果一个表的字段特别多,每次查询又不是所有的字段都能用得到 将表一分为二 用户表 用户表 id name age 用户详情表 id addr phone hobby email... 站在用户表 一个用户能否对应多个用户详情 站在详情表 一个详情能否属于多个用户 结论:单向的一对多都不成立,那么这个时候两者之间的表关系要么就是一对一,或者没有关系 一对一关系,外键字段建在任意一方都可以,但是推荐建在查询频率比较高的表中 create table authordetail( id int primary key auto_increment, phone int, addr varchar(64) ); create table author( id int primary key auto_increment, name varchar(32), age int, authordetail_id int unique, # 这里必须要唯一 foreign key(authordetail_id) references authordetail(id) on update cascade on delete cascade ); 补充:表与表之间如果有关系的话,可以有两种建立联系的方式 1:就是通过外键强制性的建立关系 2:就是自己通过sql语句逻辑层面上建立关系 delete from emp where id=1; delete from dep where id=1; 创建外键会消耗一定的资源,并且增加了表与表之间的耦合度 在实际项目中,如果表特别多,其实可以不做任何外键处理,直接通过sql语句来建立逻辑层面上的关系 到底用不用外键取决于实际项目需求 '''
修改表
''' mysql对大小写是不敏感的 1 修改表名 alter table 表名 rename 新表名; 2 增加字段 alter table 表名 add 字段名 字段类型(宽度) 约束条件; # 添加在最后面 alter table 表名 add 字段名 字段类型(宽度) 约束条件 first; # 添加在最前面 alter table 表名 add 字段名 字段类型(宽度) 约束条件 after 字段名; # 指定跟在某个字段后面 3 删除字段 alter table 表名 drop 字段名; 4 修改字段 alter table 表名 modify 字段名 字段类型(宽度) 约束条件; # modify一般都是用来修改字段的字段类型和约束条件等,不能修改字段名 alter table 表民 change 旧字段名 新字段名 字段类型(宽度) 约束条件; '''
复制表
''' sql语句的查询结果其实也是一张虚拟表 create table 新表名 select * from 旧表名; # 不能复制主键/外键... create table 新表名 select * from 旧表名 where id>1; '''