把所有数据都存放于一张表的弊端:

1、组织结构不清晰

2、浪费硬盘空间

3、扩展性极差

 

一、一对多:员工和部门

 1、如何查找表与表之间的关系

以员工和部门表为例。查找表关系需要做到换位思考(站在两边去找表关系)
    先站在员工表:
        找员工表的多条数据能否对应部门表的一条数据
        翻译:
            多个员工能否属于一个部门
            可以!之后不能直接下结论,还需要站在部门表的角度再确认关系

    再站在部门表:
        找部门表的多条数据能否对应员工表的一条数据
        翻译:
            多个部门能否有同一个员工
            不可以!
    只有站在两边表的角度都分析过了,才能够下结论
    员工表单向多对一部门表

2、外键foreign key

①在创建表时,先建被关联的表dep,才能建关联表emp
        先建被关联的表dep:
            create table dep(
                id int primary key auto_increment,
                dep_name char(16),
                dep_desc char(64)
            );

        再建关联表emp:
            create table emp(
                id int primary key auto_increment,
                name char(16),
                gender enum('male','female') not null default 'male',  # default后面的默认值空格直接书写即可
                dep_id int,
                foreign key(dep_id) references dep(id)
            );

    ②在插入数据时,必须先插入被关联的表dep,在插入关联表emp
        先插入被关联的表dep:
            insert into dep(dep_name,dep_desc) values
            ('外交部','形象代言人'),
            ('教学部','教书育人'),
            ('技术部','技术能力有限部门');

        再插入关联的表emp:
            insert into emp(name,gender,dep_id) values
            ('jason','male',1),
            ('egon','male',2),
            ('kevin','male',2),
            ('tank','male',2),
            ('jerry','female',3);

            update dep set id=100 where id=2;  会报错
            delete from dep where id=100;      会报错

            当我想修改emp里的dep_id或dep里面的id时返现都无法成功
            当我想删除dep表的教学部的时候,也无法删除

    方式1:先删除教学部对应的所有的员工,再删除教学部
    方式2:受限于外键约束,导致操作数据变得非常复杂,能否有一张简单的方式,
            让我不需要考虑在操作目标表的时候还需要考虑
            关联表的情况,比如我删除部门,那么这个部门对应的员工就应该跟着立即清空

3、怎么解决可以修改emp里的dep_id或dep里面的id(给外键字段新增功能:同步更新同步删除(级联删除级联更新)):

先把之前创建的表删除,先删员工表,再删部门表,最后按章下面的方式重新创建表关系

先建被关联的表dep:
            create table dep(
                id int primary key auto_increment,
                dep_name char(16),
                dep_desc char(64)
            );

        在建关联表emp:
            create table emp(
                id int primary key auto_increment,
                name char(16),
                gender enum('male','female','others') not null 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,gender,dep_id) values
            ('jason','male',1),
            ('egon','male',2),
            ('kevin','male',2),
            ('tank','male',2),
            ('jerry','female',3);

            update dep set id=100 where id=2;   # 把dep表中字段id是2的改成100
            delete from dep where id=100;       # 把dep表中字段id是100的删除

 

二、多对多:图书和作者

1、如何查找表与表之间的关系

仍然站在两张表的角度:
        站在图书表:一本书可不可以有多个作者,可以!那就是书多对一作者
        站在作者表:一个作者可不可以写多本书,可以!那就是作者多对一书
        双方都能一条数据对应对方多条记录,这种关系就是多对多!

    先来想如何创建表?图书表需要有一个外键关联作者,作者也需要有一个外键字段关联图书。问题来了,先创建谁都不合适!如何解决?
    建立第三张表,该表中有一个字段fk左表的id,还有一个字段是fk右表的id

2、外键foreign key

    创建book表:
        create table book(
            id int primary key auto_increment,
            title char(16),
            price int
        );
    创建author表:
        create table author(
            id int primary key auto_increment,
            name char(16),
            gender char(16)
        );
    创建book2author表:
        create table book2author(
            id int primary key auto_increment,
            book_id int,
            author_id int,
            foreign key(author_id) references author(id)
            on update cascade
            on delete cascade,
            foreign key(book_id) references book(id)
            on update cascade
            on delete cascade
        );

    表book中插入数据:
        insert into book(title,price) values
        ('金青梅','100'),
        ('围城','200'),
        ('python全栈开发','3000');
    表author中插入数据:
        insert into author(name,gender) values
        ('jason','male'),
        ('egon','female'),
        ('kevin','male');
    表book2author中插入数据:
        insert into book2author(book_id,author_id) values
        (1,1),
        (1,2),
        (1,3),
        (2,1),
        (2,3),
        (3,1),
        (3,2);

 

三、一对一:客户表和学生表

 左表的一条记录唯一对应右表的一条记录,反之也一样

   创建顾客表:
        create table customer(
            id int primary key auto_increment,
            name char(16) not null,
            qq char(16) not null,
            phone char(16) not null
        );

    创建学生表:
        create table student(
            id int primary key auto_increment,
            class_name char(20) not null,
            customer_id int unique,
            foreign key(customer_id) references customer(id)
            on delete cascade
            on update cascade
        );

总结:三种外键关系都是用foreign key,区别在于如何使用以及其他条件限制即可做出三种关系

 

四、修改表

①修改表名
        alter table 表名 rename 新表名;

②增加字段
        alter table 表名 add 字段名 数据类型[完整性约束条件];
                         add 字段名 数据类型[完整性约束条件];
        alter table 表名 add 字段名 数据类型[完整性约束条件] first;
        alter table 表名 add 字段名 数据类型[完整性约束条件] after 字段名;

③删除字段
        alter table 表名 drop 字段名;

④修改字段:modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
        alter table 表名 modify 字段名 数据类型[完整性约束条件];
        alter table 表名 change 旧字段名 新字段名 旧数据类型[完整性约束条件];
        alter table 表名 change 旧字段名 新字段名 新数据类型[完整性约束条件];

 

五、复制表

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

②只复制表结构
    create table new1_service select * from service where 1=2; 条件为假,查不到任何记录