MySQL表与表之间建关系,修改表,复制表

'''
    定义一张员工表,表中有很多字段
        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;
'''
while True: print('studying...')
原文地址:https://www.cnblogs.com/xuewei95/p/15113306.html